acadrust 0.4.1 → 0.6.5 업그레이드 보고서
+++ +대상:
+dwg-dxf-viewer-sample뷰어의 DWG 파서 wasm (hmwebviewer/rust/dwg-wasm)
+비교: acadrust 0.4.1 + 로컬 패치 (현재 배포본과 같은 wasm) ↔ acadrust 0.6.5 무수정
+작성: 2026-10-19 · 상태:수정 완료·검증됨(아래 캡처와 수치는 모두 실제 실행 결과)
1. 핵심
+-
+
- 기존 샘플 22개(DWG 21 + DXF 1)가 0.6.5 에서도 모두 정상으로 열린다. 기본 탭(Model/Layout)과 엔티티 수가 0.4.1 과 같고, 콘솔 에러는 양쪽 모두 0이다. +
- 17개는 기본 화면이 픽셀 단위로 같다. 나머지 5개는 0.4.1 이 잘못 읽던 데이터를 0.6.5 가 바로잡은 결과이며, 나빠진 화면은 없다 (§5). +
- 0.4.1 에 로컬 패치로 고쳐 두었던 두 기능(MESH, OLE2FRAME)은 0.6.5 무수정으로 화면이 픽셀 단위로 같다 (§4). 그래서 패치를 버리고 acadrust 를 고치지 않은 채로 쓸 수 있게 됐다. +
- 파싱 결과: DWG 21개, 엔티티 381,811개 전부 짝이 맞는다 (누락·추가 0). 값이 바뀐 엔티티는 2,925개(0.77 %)이며 원인을 모두 확인했다 (§7). +
- 대가: wasm 크기 brotli 294 KB → 815 KB, 브라우저 로드 시간 약 2~9 % 증가 (§9). +
2. 비교 방법
+-
+
- 같은 뷰어 코드(작업 트리)를 띄우고 파서 wasm 파일만 0.4.1 판 → 0.6.5 판으로 바꿔 같은 절차를 두 번 실행했다. +
- Chrome headless (실제 GPU, ANGLE D3D11), 화면 1280×800. 샘플마다 새 브라우저 컨텍스트에서 파일을 열고, 상태바에
✓ 파일명이 뜨면 로드 성공으로 판정했다.
+ - 캡처는 UI 패널을 숨기고 도면만 찍었다. 두 캡처를 픽셀 단위로 비교해 색 차이(RGB 합 30 초과)가 난 픽셀 비율을 "화면 차이"로 적었다. +
- 차이가 난 곳과 기존 패치 기능은 같은 좌표로 확대해 한 번 더 찍었다. 차이 이미지는 달라진 픽셀을 자홍색으로 칠한 것이다. +
- 별도로 Node 에서 두 wasm 의 파싱 결과(JSON)를 엔티티 handle 단위로 비교했다 (§7). +
3. 전체 결과
+| # | 파일 | 위치 | MB | 기본 탭 | 엔티티 | 로드 0.4.1 → 0.6.5 | 화면 차이 | 판정 |
|---|---|---|---|---|---|---|---|---|
| 1 | BasicSample.dwg | public/samples | 0.4 | Model | 7,309 | 394 → 435 ms | 0 % | 동일 |
| 2 | C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwg | public/samples | 5.4 | Layout | 17,810 | 958 → 987 ms | 0 % | 동일 |
| 3 | C0060203-001-표준단면도(2차로,자연환기300m이상).dwg | public/samples | 0.4 | Model | 2,068 | 347 → 412 ms | 0 % | 동일 |
| 4 | C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg | public/samples | 0.8 | Model | 5,979 | 314 → 356 ms | 0.02 % | 개선 |
| 5 | bb.dwg | public/samples | 0.7 | Layout | 438 | 231 → 307 ms | 0 % | 동일 |
| 6 | dwg_1.60mb.dwg | public/samples | 1.6 | Model | 21,330 | 1,139 → 1,253 ms | 0.0089 % | 개선 |
| 7 | dwg_18.3mb.dwg | public/samples | 18.4 | Model | 82,393 | 3,920 → 4,024 ms | 0 % | 동일 |
| 8 | simple.dxf | public/samples | 0.0 | — | 6 | 55 → 54 ms | 0 % | 동일 |
| 9 | 04manhole1-simplify.dwg | dist2/samples | 0.4 | Layout | 7,035 | 357 → 421 ms | 0 % | 동일 |
| 10 | 대산당진 2공구_노면_20260804_143854.dwg | dist2/samples | 37.1 | Model | 65,495 | 5,651 → 5,737 ms | 0 % | 동일 |
| 11 | test.dwg | dist2/samples | 18.4 | Model | 82,393 | 3,719 → 4,043 ms | 0 % | 동일 |
| 12 | a. 거더배치 삽도_25.02.28.dwg | dwg2model | 0.2 | Layout | 1,433 | 453 → 484 ms | 0 % | 동일 |
| 13 | a. 교대배치 삽도_25.02.28.dwg | dwg2model | 0.4 | Layout | 2,138 | 320 → 293 ms | 0 % | 동일 |
| 14 | a. 교량시종점 삽도_25.02.28.dwg | dwg2model | 0.4 | Layout | 4,432 | 377 → 353 ms | 3.45 % | 개선 |
| 15 | a. 교량폭원 삽도_25.02.28.dwg | dwg2model | 0.5 | Layout | 2,824 | 210 → 258 ms | 0 % | 동일 |
| 16 | a. 교면포장 삽도_25.02.28.dwg | dwg2model | 0.2 | Layout | 1,304 | 176 → 226 ms | 0 % | 동일 |
| 17 | a. 중앙분리대 삽도_25.02.28.dwg | dwg2model | 0.4 | Layout | 2,159 | 267 → 260 ms | 18.37 % | 개선 |
| 18 | a. 횡단경사 삽도_25.02.28.dwg | dwg2model | 0.5 | Layout | 5,635 | 343 → 341 ms | 0 % | 동일 |
| 19 | 산외교- ELEVATION 산출근거도 (울산방향).dwg | dwg2model | 0.6 | Model | 11,262 | 740 → 818 ms | 0.0047 % | 개선 |
| 20 | 산외교-받침배치도 (울산방향) .dwg | dwg2model | 0.4 | Model | 6,240 | 590 → 689 ms | 0 % | 동일 |
| 21 | 산외교_파이형_교각일반도(울산P11-꺾임).dwg | dwg2model | 1.0 | Model | 25,927 | 707 → 731 ms | 0 % | 동일 |
| 22 | 산외교_파이형_교각일반도(울산P9).dwg | dwg2model | 1.0 | Model | 26,207 | 732 → 710 ms | 0 % | 동일 |
로드 시간은 파일 선택부터 상태바 ✓ 표시까지(파싱 + 렌더). simple.dxf 는 wasm 이 아니라 dxf-parser 로 읽으므로 대조군이다. dwg_18.3mb.dwg 와 test.dwg 는 바이트는 다르지만 같은 도면이다.
4. 0.4.1 로컬 패치 기능 — 0.6.5 무수정으로 동일
+0.4.1 에서는 아래 두 가지를 acadrust 소스를 고쳐서 해결했다. 0.6.5 는 고치지 않은 상태로 같은 화면을 낸다.
+MESH(SubDMesh) — 노면·부체도로면 삼각망
+대산당진 2공구_노면_20260804_143854.dwg · 확대 화면 차이 0 %
+| 0.4.1 + 로컬 패치 | 0.6.5 무수정 |
|---|---|
0.4.1 원본은 10만 개 상한에서 배열이 잘려 메쉬가 깨졌다 (verts 100000 / faces 14). 패치본과 0.6.5 모두 verts 105,497 / faces 185,444 / edges 290,931.
+OLE2FRAME — 삽입 이미지와 위치
+C0060203-001-표준단면도(2차로,자연환기300m이상).dwg · 확대 화면 차이 0 %
+| 0.4.1 + 로컬 패치 | 0.6.5 무수정 |
|---|---|
0.4.1 원본은 프레임 좌표를 읽지 못했다 ((1,1,0)–(0,0,0)). 패치본과 0.6.5 모두 (20584.21, 25712.29)–(39654.45, 13712.29), 추출 이미지 바이트도 동일.
+ +5. 화면이 달라진 5개 — 원인과 판정
+모두 0.4.1 이 잘못 읽던 값을 0.6.5 가 바로잡은 경우다. 차이 이미지에서 자홍색이 달라진 픽셀이다.
+a. 중앙분리대 삽도_25.02.28.dwg
+개선 레이아웃 전체 뷰포트를 모델 창으로 오판하던 것이 해소 — 도면을 가로지르던 검은 세로 띠가 사라지고 Fit 이 도면을 채움 · 기본 화면 차이 18.37 %
+| 0.4.1 | 0.6.5 | 차이 |
|---|---|---|
a. 교량시종점 삽도_25.02.28.dwg
+개선 트루컬러 해치(RGB 128,93,59)의 근사 색이 ACI 35 → 37 로 바뀌어 원본에 더 가까워짐 · 기본 화면 차이 3.45 % · 확대 화면 차이 7.80 %
+| 0.4.1 | 0.6.5 | 차이 |
|---|---|---|
C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg
+개선 ATTDEF 정렬을 새로 읽어 동그라미 번호(①)가 원의 오른쪽 아래에서 중앙으로 옮겨짐 · 기본 화면 차이 0.02 % · 확대 화면 차이 0.02 %
+| 0.4.1 | 0.6.5 | 차이 |
|---|---|---|
dwg_1.60mb.dwg
+개선 3D 폴리선 vertex 순서 수정 — 곡선을 가로지르던 가짜 직선(청록)이 사라짐 · 기본 화면 차이 0.0089 % · 확대 화면 차이 0.48 %
+| 0.4.1 | 0.6.5 | 차이 |
|---|---|---|
산외교- ELEVATION 산출근거도 (울산방향).dwg
+개선 작은 표고 텍스트 2곳의 위치 (ATTDEF 정렬) · 기본 화면 차이 0.0047 %
+| 0.4.1 | 0.6.5 | 차이 |
|---|---|---|
6. 전체 샘플 화면 비교 (기본 화면)
+파일을 열었을 때 처음 보이는 화면이다. 이미지를 누르면 크게 볼 수 있다.
+| 파일 | 0.4.1 | 0.6.5 |
|---|---|---|
| 1. BasicSample.dwg Model · 7,309 엔티티 픽셀 동일 | ||
| 2. C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwg Layout · 17,810 엔티티 픽셀 동일 | ||
| 3. C0060203-001-표준단면도(2차로,자연환기300m이상).dwg Model · 2,068 엔티티 픽셀 동일 | ||
| 4. C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg Model · 5,979 엔티티 개선 · 0.02 % §5 참고 | ||
| 5. bb.dwg Layout · 438 엔티티 픽셀 동일 | ||
| 6. dwg_1.60mb.dwg Model · 21,330 엔티티 개선 · 0.0089 % §5 참고 | ||
| 7. dwg_18.3mb.dwg Model · 82,393 엔티티 픽셀 동일 | ||
| 8. simple.dxf — · 6 엔티티 픽셀 동일 | ||
| 9. 04manhole1-simplify.dwg Layout · 7,035 엔티티 픽셀 동일 | ||
| 10. 대산당진 2공구_노면_20260804_143854.dwg Model · 65,495 엔티티 픽셀 동일 | ||
| 11. test.dwg Model · 82,393 엔티티 픽셀 동일 | ||
| 12. a. 거더배치 삽도_25.02.28.dwg Layout · 1,433 엔티티 픽셀 동일 | ||
| 13. a. 교대배치 삽도_25.02.28.dwg Layout · 2,138 엔티티 픽셀 동일 | ||
| 14. a. 교량시종점 삽도_25.02.28.dwg Layout · 4,432 엔티티 개선 · 3.45 % §5 참고 | ||
| 15. a. 교량폭원 삽도_25.02.28.dwg Layout · 2,824 엔티티 픽셀 동일 | ||
| 16. a. 교면포장 삽도_25.02.28.dwg Layout · 1,304 엔티티 픽셀 동일 | ||
| 17. a. 중앙분리대 삽도_25.02.28.dwg Layout · 2,159 엔티티 개선 · 18.37 % §5 참고 | ||
| 18. a. 횡단경사 삽도_25.02.28.dwg Layout · 5,635 엔티티 픽셀 동일 | ||
| 19. 산외교- ELEVATION 산출근거도 (울산방향).dwg Model · 11,262 엔티티 개선 · 0.0047 % §5 참고 | ||
| 20. 산외교-받침배치도 (울산방향) .dwg Model · 6,240 엔티티 픽셀 동일 | ||
| 21. 산외교_파이형_교각일반도(울산P11-꺾임).dwg Model · 25,927 엔티티 픽셀 동일 | ||
| 22. 산외교_파이형_교각일반도(울산P9).dwg Model · 26,207 엔티티 픽셀 동일 |
7. 파싱 데이터 비교
+Node 에서 두 wasm 으로 같은 DWG 21개를 파싱해 엔티티를 타입#handle 로 짝지은 뒤 필드별로 비교했다. 파일별 엔티티 수와 handle 집합은 완전히 같고, 값이 바뀐 필드는 아래가 전부다.
| 바뀐 값 | 필드 변경 건수 | 파일 수 | 원인 | 화면 영향 |
|---|---|---|---|---|
치수 정의점 pt10 | 1,175 | 12 | 0.4.1 이 (0,0,0) 으로 냄 → 실제 좌표 | 블록 없는 치수(대체 렌더)의 선택 범위·extents 만 |
| ATTDEF 정렬점·정렬·폭 비율 | 2,171 | 14 | 0.4.1 이 읽지 못함 → 실제 값 | 블록 안 속성 텍스트 위치·폭이 정확해짐 |
| 익명 블록 이름 | 812 | 1 | 번호 체계 변경 (*U1 → *U7) | 없음 — 렌더는 handle 기준, 이름·블록 테이블 불일치 0건 |
| 트루컬러 엔티티의 근사 ACI | 116 | 3 | 근사 계산 개선 (원본 RGB 는 동일) | 원본 색에 더 가까워짐 |
| VIEWPORT id 0 → 1 | 27 | 10 | 0.6.5 가 레이아웃 전체 뷰포트에 id 1 부여 | 전체 뷰포트 오판 해소 (중앙분리대 검은 띠) |
| VIEWPORT 상태 비트 | 26 | 2 | 비트 0x10000 추가 | 없음 (Viewer2D 는 isOn 만 사용) |
| 3D 폴리선 점 순서 | 7 | 1 | 0.4.1 이 vertex 를 handle 순으로 정렬 | 가짜 직선 제거 (dwg_1.60mb) |
| 텍스트 내용 | 1 | 1 | CP949 기호 디코딩 (500¡¿350 → 500×350) | 깨진 기호 1건 해소 |
| OLE 데이터 길이 | 1 | 1 | 페이로드 재조립으로 512 B 차이 | 없음 (추출 이미지 바이트 동일) |
한글: 0.4.1 은 평면및종단면도(153개)와 굴착및시공순서도(160개)의 한글을 Latin-1 로 깨진 채 내보냈고, 뷰어의 JS 보정(fixDwgKoreanText)이 복원해 왔다. 0.6.5 는 DWG 21개 전부 처음부터 정상 디코딩한다(깨짐 0). 보정 후 한글 텍스트 수는 두 버전이 모든 파일에서 같다.
8. 업그레이드에서 바꾼 것
+acadrust 는 crates.io 의 0.6.5 를 고치지 않고 쓴다 (acadrust = "=0.6.5"). 0.6.5 에 맞추느라 바꾼 곳은 전부 우리 래퍼 dwg-wasm(MIT) 안이다.
| 변경 | 이유 |
|---|---|
vendored rust/acadrust/(189개 파일) 삭제, crates.io 버전 고정 | 무수정 사용. 고지에 적은 버전과 빌드 소스를 일치시킨다 |
손상 레코드 허용 모드(failsafe)로 읽기 | 0.6.5 기본 모드는 레코드 하나만 깨져도 도면 전체를 거부한다. a. 거더배치 삽도 가 통째로 열리지 않았다. 허용 모드에서는 정상으로 열리고, 건너뛴 레코드는 알림으로 남는다 |
| wasm 메모리를 32 MB 단위로 확장하는 할당자 | 그대로 올리면 37 MB 노면 도면 파싱이 3.0 초 → 7.4 초로 느려졌다. 원인은 브라우저 엔진(V8)에서 메모리를 늘리는 비용이 현재 메모리 크기에 비례하는데, 0.6.5 가 64 KB 단위로 수천 번 늘렸기 때문이다 (프로파일로 확인). 수정 후 3.3 초 |
| API 변경 대응 (치수 Box 타입, OLE 페이로드) | 컴파일 에러 9개. OLE 이미지 추출 결과는 기존과 바이트 단위로 같다 |
9. 성능·크기
+| 항목 | 0.4.1 + 패치 | 0.6.5 |
|---|---|---|
| wasm 크기 (원본 / brotli 압축) | 864 KB / 294 KB | 2,976 KB / 815 KB |
| 브라우저 로드 — 대산당진 노면 (37 MB) | 5,651 → 5,737 ms | |
| 브라우저 로드 — dwg_18.3mb (18 MB) | 3,920 → 4,024 ms | |
| Node 파싱만 — 노면 / dwg_18.3mb | 3.0 s / 1.9 s | 3.3 s / 2.1 s |
| wasm 메모리 — 노면 / dwg_18.3mb | 672 / 546 MB | 773 / 505 MB |
크기가 커진 것은 acadrust 0.6 이 DXF/DWG 쓰기, ACIS 등을 포함해 라이브러리 자체가 커졌기 때문이다. 끌 수 있는 기능 옵션은 없다. 크기 우선 최적화(opt-level = "z")도 시험했으나 815 → 742 KB(−9 %)를 얻는 대신 파싱이 36 % 느려져 채택하지 않았다.
10. 라이선스 영향
+-
+
- 0.4.1 은 acadrust 를 2개 파일 3곳 고쳐 쓰고 있었고, 공개한 패치는 원본에 적용되지 않아 배포 wasm 의 소스를 재현할 수 없었다 (MPL-2.0 §3.2 미충족). +
- 0.6.5 는 무수정이므로 MPL-2.0 의무가 라이선스 원문 동봉 + 소스 입수 위치 고지로 줄어든다. 고지에는 crates.io 다운로드 주소, upstream 커밋, crate SHA-256(빌드에 쓴
Cargo.lockchecksum 과 일치)을 적었다.
+ - 공개 배포본(pages.dev)은 재빌드·재배포 전까지 옛 고지(0.4.1 패치)를 보여 준다. +
11. 남은 것
+-
+
- pages.dev 재배포 (현재 공개본은 0.4.1 wasm + 옛 고지) +
- 뷰어가 0.6.5 에서 새로 읽히는 호 길이 치수·대형 반경 치수(
DIMENSION_ARC,DIMENSION_LARGE_RADIAL)를 아직 그리지 않는다. 샘플 22개에는 해당 엔티티가 없다.
+ - XDATA 는 acadrust 가 읽지만 뷰어 출력에는 넣지 않는다 (업그레이드 전과 같음). +
- wasm 에 들어가는 Rust 의존 라이브러리(MIT/Apache/BSD 등)의 고지 생성. +
검증하지 못한 것
+| 항목 | 이유 |
|---|---|
| AutoCAD 원본 화면과의 대조 | 같은 위치의 AutoCAD 정답 캡처가 없다. 개선 판정은 데이터 근거(원본 RGB, vertex 좌표의 연속성, 뷰포트 id·배율)에 기댄다 |
| Firefox / Safari 에서의 로드 시간 | Chrome 과 Node 에서만 측정 |
| Layout/Model 탭을 바꾼 뒤의 화면, 2.5D 보기 | 기본 화면과 지정 확대 화면만 캡처 |