Re-test of every sample in the browser viewer and headless Node, the history of 13 handled errors with before/after/current captures for the 8 that could be reproduced, newly found issues (Fit cropping, %%% control codes, symbol-only CP949 strings, broken e2e) and the library packaging assessment. scripts/parse-dwg.mjs is the headless parser used for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
26 KiB
샘플 테스트·오류 처리 현황 보고서 (2026-10-19)
대상:
dwg-dxf-viewer-sample(HEAD1f80442+ 미커밋 작업 트리) 근거: 이번 재테스트 실측, git 이력 20커밋,docs/*.md10건,hmwebviewer/PROGRESS.md상태 표기:원인 확정·수정 완료·검증됨·수정 완료·미검증이 보고서에는 검증된 결과만 싣는다. 검증하지 못한 항목은 §8 목록에만 적는다.
1. 핵심
- 고유 샘플 20개(DWG 19 + DXF 1)가 모두 브라우저 뷰어에서 로드에 성공했다. 콘솔 에러는 404 리소스 1건뿐이다. Node 헤드리스 파싱도 19/19 성공했다.
- 기존 e2e(
e2e_lin_test.cjs)는 지금 상태 그대로는 실패한다 (ERR_MODULE_NOT_FOUND). 끝까지 돌려도 assert 가 없어서 결과를 판정하지 못한다. - 과거에 처리한 오류 13건 중 8건을 검증했다 (§4.1). 해당 커밋의 수정 전 버전과 수정 후 버전을 실제로 띄워서, 현재 버전까지 3단으로 캡처하고 측정했다.
- 대용량 로드: 213.8초 → 3.6초
- Slug 글자 높이: 150px → 202px (비율 0.743, 커밋 주장 0.744)
- 레이어 토글: 454
622ms → 1335ms - 그 외 회색 원 제거, 메쉬 표시, 선가중치 적용, Model/Paper 분리, 한글 복원
- 이번에 새로 찾은 문제는 4건이다.
- Fit 이 도면 가장자리를 잘라냄
%%%제어코드가 변환되지 않음- 기호만 있는 CP949 문자열이 깨진 채 남음
- e2e 스크립트가 고장 나 있음
- 라이선스 2건 (
원인 확정)- 공개한 MPL 패치를 원본 acadrust 0.4.1 에 적용하면 실패한다. 실제 wasm 의 소스를 재현할 수 없다는 뜻이다.
- Visio 저작권("All rights reserved") 라인타입 데이터가 번들에 들어 있다.
- Gitea 와 dist2 는 사내 전용이다. 외부 반출(고객 납품·외부 웹 공개·npm) 전에 해결해야 한다. 라이선스 고지 버튼 자체는 형식이 맞다. 그 버튼이 가리키는 패치 내용이 틀렸다.
- 라이브러리 배포는 조건부로 가능하다 (§6). 위 라이선스 2건, Vite 전용 코드, Viewer2D 에
dispose()가 없는 문제를 먼저 해결해야 한다.
2. 권장 액션
- 라이선스.
- MPL 패치를 다시 만든다. 원본 0.4.1 과 실제 vendored 트리의 전체 diff 로 만들고, 원본에 적용해서 성공하는지 확인한다.
- 고지 문서 4곳의 "한 파일만 수정", "unmodified" 문구를 고친다.
ICAD_LIN은 IntelliCAD(ITC) 계약 범위를 확인한다. 외부 배포가 허용되지 않으면 제거한다.
- 미커밋 작업 정리.
- 2.5D 보기, VIEWPORT 채움 변환, Z 붕괴 수정을 커밋하거나 분리한다.
- 루트의 untracked 대용량 파일(
C0060202.json31.7MB,SAN01.json16.6MB,C0060202.zip)은.gitignore에 넣거나 삭제한다.
- e2e 를 실제 테스트로.
linParser.ts의 확장자 없는 import 를 고친다.- 샘플 경로를
dist/에서public/samples/로 바꾼다. - assert 를 추가한다.
- 이번에 쓴 브라우저 e2e 와 3단 비교 스크립트를 레포에 넣는다.
- Fit 잘림 수정 (§3.4-①).
- 텍스트 후처리 2건 수정.
stripMText에%%%,%%nnn,%%o,%%u처리를 추가한다.fixCp949Mojibake가 한글이 없는 CP949 기호도 복원하게 한다.
3. 이번 재테스트 결과
3.1 환경
| 항목 | 값 |
|---|---|
| 코드 | HEAD 1f80442 + 미커밋 변경(2.5D 보기, _bakeFillXf, _trimmedContentBox Z 수정) |
| Node | v24.11.1 |
| 브라우저 | 시스템 Chrome headless, playwright-core@1.56.1 |
| GPU | ANGLE D3D11 / NVIDIA RTX 3060 (실제 GPU) |
| 타입체크 | npm run typecheck 통과 (컴파일 통과일 뿐, 동작 검증은 아님) |
3.2 샘플별 결과
열 설명:
- Node 파싱:
parse_dwg_json+fixDwgKoreanText실행 시간. - RSS: 프로세스 전체 메모리.
- 브라우저 로드: 파일을 선택한 뒤 상태바에
✓ <파일명>이 뜨기까지의 시간. - JS heap:
performance.memory. - notif: acadrust notification 개수.
| 파일 | MB | 버전 | 엔티티 | Node 파싱 ms | RSS MB | 브라우저 로드 ms | JS heap MB | 콘솔 에러 | notif | 결과 |
|---|---|---|---|---|---|---|---|---|---|---|
| BasicSample.dwg | 0.4 | R2018 | 7,309 | 142 | 147 | 553 | 47 | 1¹ | 4 | 통과 |
| civil.dwg² | 5.4 | R2000 | 17,810 | 389 | 264 | 799 | 98 | 0 | 2 | 통과 |
| C0060203-001-표준단면도(…).dwg | 0.4 | R2007 | 2,068 | 93 | 126 | 567 | 57 | 0 | 78 | 통과 |
| bb.dwg | 0.7 | R2018 | 438 | 75 | 109 | 579 | 46 | 0 | 4 | 통과 |
| simple.dxf | 0.0 | DXF | 6 | — | — | 74 | 34 | 0 | — | 통과 |
| 04manhole1-simplify.dwg | 0.4 | R2018 | 7,035 | 118 | 138 | 575 | 54 | 0 | 4 | 통과 |
| dwg_18.3mb.dwg | 18.4 | R2018 | 82,393 | 1,988 | 1,087 | 4,232 | 372 | 0 | 4 | 통과 |
| test.dwg³ | 18.4 | R2018 | 82,393 | 2,156 | 1,088 | 3,914 | 371 | 0 | 4 | 통과 |
| 대산당진 2공구_노면_….dwg | 37.1 | R2018 | 65,495 | 3,017 | 1,373 | 5,454 | 782 | 0 | 4 | 통과 |
| a. 거더배치 삽도 | 0.2 | R2018 | 1,433 | 118 | 134 | 568 | 139 | 0 | 5 | 통과 |
| a. 교대배치 삽도 | 0.4 | R2018 | 2,138 | 58 | 102 | 565 | 59 | 0 | 4 | 통과 |
| a. 교량시종점 삽도 | 0.4 | R2018 | 4,432 | 84 | 105 | 542 | 56 | 0 | 4 | 통과 |
| a. 교량폭원 삽도 | 0.5 | R2018 | 2,824 | 64 | 106 | 575 | 45 | 0 | 4 | 통과 |
| a. 교면포장 삽도 | 0.2 | R2018 | 1,304 | 54 | 104 | 570 | 44 | 0 | 4 | 통과 |
| a. 중앙분리대 삽도 | 0.4 | R2018 | 2,159 | 63 | 103 | 537 | 44 | 0 | 4 | 통과 |
| a. 횡단경사 삽도 | 0.5 | R2018 | 5,635 | 126 | 138 | 569 | 44 | 0 | 4 | 통과 |
| 산외교- ELEVATION 산출근거도 | 0.6 | R2007 | 11,262 | 162 | 181 | 937 | 111 | 0 | 44 | 통과 |
| 산외교-받침배치도 | 0.4 | R2018 | 6,240 | 106 | 144 | 635 | 63 | 0 | 4 | 통과 |
| 산외교_파이형_교각일반도(울산P11-꺾임) | 1.0 | R2018 | 25,927 | 371 | 219 | 810 | 56 | 0 | 4 | 통과 |
| 산외교_파이형_교각일반도(울산P9) | 1.0 | R2018 | 26,207 | 397 | 220 | 744 | 57 | 0 | 4 | 통과 |
¹ 404 리소스 1건, 첫 페이지에서만 발생. /favicon.ico 가 404 를 반환하는 것은 확인했다.
² civil.dwg 와 C0060202-001-평면및종단면도(…).dwg 는 md5 가 같다. 같은 파일이다.
³ test.dwg 는 dwg_18.3mb.dwg 와 바이트는 다르지만, 파싱 결과의 엔티티 수와 텍스트 통계가 같다.
"통과" 의 기준: 상태바에 ✓ <그 파일명> · … entities 가 표시되고, .err 가 없고, 페이지 crash 가 없을 것.
3.3 기존 e2e (e2e_lin_test.cjs)
| 실행 방식 | 결과 |
|---|---|
node e2e_lin_test.cjs (그대로) |
실패, exit 1. 4단계에서 ERR_MODULE_NOT_FOUND: …/src/viewer2d/linData |
| resolve hook 추가 | 끝까지 실행, exit 0. H-DICHL06/06R/02R/01R/05 패턴 5개 출력 |
원인 확정: linParser.ts 가 ./linData 를 확장자 없이 import 한다. Vite 는 이것을 해석하지만 Node ESM 은 해석하지 못한다.
그 밖의 문제:
- assert 가 없다. 패턴을 못 찾아도
console.error만 찍고, 마지막에 항상COMPLETED SUCCESSFULLY를 출력한다. - 샘플 경로가 gitignore 된
./dist/samples/…다. clean checkout 에서는 실패한다. - 느린 경로인
parse_dwg를 쓰고fixDwgKoreanText를 적용하지 않는다. 그래서 출력되는 라인타입 설명이LÇüÃø±¸처럼 깨진다. Found 0 text styles가 출력된다.tables.styles가 비어 있다는 문서상 과제가 C0060202 에서도 재현된다.
3.4 이번에 새로 확인한 문제
① Fit 이 도면 가장자리를 잘라냄. 재현 확인.
- ELEVATION 도면에서 Fit 을 하면 도곽 왼쪽이 화면 밖으로 나가고, 오른쪽에는 약 470px 가 비어 있다 (§4.1 캡처).
- 자동 Fit, Fit 버튼, 창 크기 변경 후 Fit 모두 같은 결과다.
- HEAD(미커밋 변경 제외)에서도 똑같다. WIP 회귀가 아니다.
② AutoCAD 제어코드 %%% 등이 변환되지 않음. 원인 확정.
- C0060203 에
-2 %%%, civil Layout 에S=0.0000%%%가 그대로 표시된다. Viewer2D.js:64의stripMText는%%d,%%p,%%c만 처리한다.
③ 기호만 있는 CP949 문자열이 깨진 채 남음. 원인 확정.
- civil 에
500¡¿350이 표시된다. CP949 로 디코딩하면500×350이다. fixDwgKoreanText.ts:64-67는 디코딩 결과에 한글이 생길 때만 변환을 받아들인다.
④ e2e 스크립트 고장. §3.3 참고.
기타 (경미)
- Layout 탭 이름이
Layout (Paper_Space0)처럼 내부 블록명으로 나온다. dwg2model 삽도 7개 전부가 그렇다. - Layout 탭이 많으면 툴바가 줄바꿈되면서 상태바가 속성 패널과 겹친다.
parse_dwg_json은 acadrust notification 의 개수만 돌려주고 내용은 돌려주지 않는다 (C0060203 78건, ELEVATION 44건).
4. 처리된 오류 이력
표기: [M] 커밋 메시지 · [D] diff 로 확인 · [Doc] 문서 기록.
Rust 쪽 수정(dwg-wasm, acadrust)은 hmwebviewer/rust/dwg-wasm 에 있다.
| # | 시기 | 증상 | 재현 샘플 | 원인 | 조치 | 커밋 | 이번 검증 |
|---|---|---|---|---|---|---|---|
| 1 | 07-30 | 구형 한글 TEXT/MTEXT 깨짐 | civil 외 | CP949 바이트가 Latin-1 로 올라옴 [Doc] | fixDwgKoreanText.ts (뷰어) |
be8d52f |
수정 완료·검증됨 (§4.1-①) |
| 2 | 07-30 | Model 과 Paper 동시 렌더, Layout 비어 보임, Fit/좌표, 글자 거대, VP 순서 (6건) | C0060202 | VIEWPORT 미투영, minTextH 등 [Doc] | cadSpaces.ts, Viewer2D (뷰어) |
be8d52f |
수정 완료·검증됨 (§4.1-②) |
| 3 | 07-30 | Brave/Firefox 에서 OLE BMP 미표시 | — | <img> 가 data:image/bmp 미지원 [M] |
순수 JS BMP 디코더 [D] | 963a903 |
§8 |
| 4 | 07-30 | OLE2FRAME 이 하드코딩된 좌표에 고정됨 | — | 정답 좌표 하드코딩 [D] | 파서가 준 ul/lr 사용 | 76f3e20 |
§8 |
| 5 | 08-03 | Slug 텍스트 cap-height 약 26% 작음 | BasicSample | 3d3e052 의 회귀 [D] |
되돌림 | fb8f7ca |
수정 완료·검증됨 (§4.1-④) |
| 6 | 08-03 | 19MB DWG 로딩 시 탭 프리즈 | dwg_18.3mb | wasm 힙 O(n²) [M] | parse_dwg_json 스트리밍 |
b047dc4 |
수정 완료·검증됨 (§4.1-③) |
| 7 | 08-03 | 도면 위아래 거대 회색 원 | dwg_18.3mb | sample_arc 각도 swap 등 [Doc] |
손상 호 감지 후 생략 (파서) | b047dc4 |
수정 완료·검증됨 (§4.1-③) |
| 8 | 08-04 | 레이어 토글 지연 | dwg_18.3mb | 토글마다 load() 재빌드 [M] |
setDrawRange, .visible 토글 |
3480945 |
수정 완료·검증됨 (§4.1-⑦) |
| 9 | 08-04 | 노면/부체도로면(MESH) 미표시 | 대산당진 노면 | MESH 직렬화 누락, read_mesh 100k 상한 [M] | acadrust 패치 + 직렬화 + _meshSegs |
eec3382, c67a803 |
수정 완료·검증됨 (§4.1-⑤) |
| 10 | 08-04 | 모든 선이 1px | 대산당진 노면 | lineWeight 누락, WebGL linewidth 무시 [M] | LineSegments2 버킷 | c67a803 |
수정 완료·검증됨 (§4.1-⑥) |
| 11 | 08-04~05 | 선가중치 배율 (8 → 20 → 11 px/mm) | 대산당진 노면 | 배율 [M] | 기본값 11, 옵션 패널 | cf12987, a924b1e, 1f80442 |
굵기 적용 확인 (§4.1-⑥). 배율 일치는 §8 |
| 12 | 08-04 | MPL-2.0 고지 누락 | — | 고지/원문/소스 경로 없음 [M] | NOTICES, public/licenses/ |
ce3859c |
조치 불충분: 패치가 원본에 적용되지 않음 (§5 A-1) |
| 13 | 08-04 | vite build 가 dist2 테스트 파일을 삭제 |
— | emptyOutDir 기본값 [M] |
--emptyOutDir false 절차 문서화 |
6f200ef |
— |
분리 전 hmwebviewer 에서 처리한 것 (07-10~14, PROGRESS.md):
- solid HATCH 구멍, HIDDEN/CENTER 파선 무시
- MAX_TEXTS 3000 상한
- 회전 도곽 viewTwist, 로고 해치, 폴리라인 폭, MTEXT 배경
미커밋 수정 2건 (수정 완료·미검증):
- VIEWPORT 안 SOLID/HATCH 채움에 model→paper 변환 추가 (
_fillXf/_bakeFillXf) _trimmedContentBox의 Z 붕괴 수정
4.1 수정 전 / 수정 후 / 현재 비교 캡처
방법
- 각 버전은
git archive <커밋>으로 풀어서 실행했다. wasm 이 커밋마다 함께 커밋돼 있어서, 그 시점의 파서와 뷰어가 같이 재현된다. - 계측용으로 두 가지만 덧붙였다. 둘 다 동작에는 영향이 없다.
main.ts에window.__viewer = viewer1줄- vite 캐시 경로 분리
- "현재" 는 오늘의 작업 트리다.
- 로드 판정은 상태바가
✓ <그 파일명> ·으로 바뀌었는지로 했다. - 확대 화면은 모든 버전에서 같은 WCS 좌표와 화면 폭으로 카메라를 고정했다. 파일럿 캡처로 목표 객체가 화면 중앙에 오는 것을 먼저 확인했다.
- UI 패널은 숨기고 캔버스만 찍었다. 해상도 1280×800, RTX 3060.
- 24회 실행 모두 로드 성공, 콘솔 에러 0건.
① 한글 깨짐 (civil.dwg)
수정 전 버전의 wasm 이 실제로 내보낸 문자열과, 수정 후 화면을 함께 비교했다:
| handle | 수정 전 95fa6a4 wasm 출력 |
수정 후 be8d52f |
|---|---|---|
| 3232403 | Ãø Á¡ |
측 점 |
| 3232405 | °èȹ°í |
계획고 |
| 3232408 | Áö¹Ý°í |
지반고 |
| 3240601 | õÀÇ1Áö±¸ °èȹ¼± |
천의1지구 계획선 |
| 3241973 | (»ç¾÷ ÁøÇà ¿¹Á¤) |
(사업 진행 예정) |
| 1009 | °Ç¼³´Ü°è |
건설단계 |
수정 후 be8d52f |
현재 |
|---|---|
![]() |
![]() |
② Model/Paper 겹침, Layout 비어 보임 (civil.dwg, 로드 직후 기본 화면)
수정 전 95fa6a4 |
수정 후 be8d52f |
현재 |
|---|---|---|
![]() |
![]() |
![]() |
| 점 3개만 보임. Model(x≈600k·162k)과 Paper(원점)를 한꺼번에 Fit 함 | Layout 이 열리고 VIEWPORT 내용이 투영됨 | 같음 (밝은 종이 배경) |
③ 대용량 로딩 + 거대 회색 원 (dwg_18.3mb.dwg, 로드 직후 기본 화면)
수정 전 7a6edd4 |
수정 후 b047dc4 |
현재 |
|---|---|---|
![]() |
![]() |
![]() |
| 로드 213.8초. 회색 SOLID HATCH 가 도면 아래쪽 절반을 덮음 | 3.6초, 회색 채움 없음 | 3.7초 |
④ Slug 텍스트 크기 (BasicSample.dwg, "정면도" h=140 주변 고정 화면)
수정 전 b047dc4 |
수정 후 fb8f7ca |
현재 |
|---|---|---|
![]() |
![]() |
![]() |
| 글자 높이 150px | 202px | 202px |
- 자홍색 픽셀 bbox 높이를 쟀다. 비율 150/202 = 0.743 으로, 커밋 메시지 "3.6 → 2.68 (0.744)" 와 일치한다.
- 주변 선과 치수의 위치는 세 장 모두 같다.
⑤ SubDMesh(MESH) 미표시 (노면 도면, 연결부 (156542, 479804), 폭 160)
수정 전 6f200ef |
수정 후 c67a803 |
현재 |
|---|---|---|
![]() |
![]() |
![]() |
| 삼각망 없음 | 도로면·부체도로면 삼각망 표시 | 같음 |
c67a803 에는 선가중치 수정도 함께 들어 있다.
⑥ 선가중치 (⑤와 같은 화면)
수정 전 eec3382 |
수정 후 1f80442 (11 px/mm) |
현재 |
|---|---|---|
![]() |
![]() |
![]() |
| 0.50mm 도로마킹 포함 모든 선 1px (메쉬 렌더러 이전 버전) | 굵게 표시 | 같음 |
⑦ 레이어 토글 속도 (dwg_18.3mb.dwg, setHiddenLayers(CF-PATT) 숨김→표시 3회, 동기 실행 시간)
수정 전 fb8f7ca |
수정 후 3480945 |
현재 | |
|---|---|---|---|
| 숨김 ms | 565 / 454 / 512 | 18 / 17 / 13 | 21 / 18 / 13 |
| 표시 ms | 501 / 622 / 609 | 26 / 5 / 6 | 35 / 5 / 5 |
새로 확인한 문제 (현재 버전)
%%% 미변환 (C0060203) |
CP949 기호 잔존 (civil) | Fit 잘림 (ELEVATION) |
|---|---|---|
![]() |
![]() |
![]() |
-2 %%% (정답 -2 %) |
500¡¿350 (정답 500×350) |
왼쪽 잘림, 오른쪽 약 470px 공백 |
5. 남은 과제
A. 우선 처리
| # | 과제 | 근거 |
|---|---|---|
| A-1 | MPL 패치가 실제 소스를 재현하지 못함 (원인 확정)- public/licenses/acadrust-0.4.1-read_mesh.patch 를 원본 acadrust 0.4.1 crate 에 git apply --check 하면 entities.rs:2350(read_ole2frame)에서 실패한다.- 고지의 "One file differs", "exact Source Code Form" 문구와 acadrust-dwg/package.json 의 "used unmodified" 가 사실과 다르다. |
이번 실행, THIRD-PARTY-NOTICES.md |
| A-2 | Visio 저작권 데이터가 번들됨 - linData.ts 의 ICAD_LIN 헤더가 "Copyright (c) 1998 by Visio Corporation. All rights reserved" 다.- linParser.ts:228 이 import 될 때 등록하므로 배포본에 반드시 들어간다.- IntelliCAD(ITC) 계약이 자사 웹 뷰어로의 외부 배포를 허용하는지 확인이 필요하다. |
이번 확인 |
| A-3 | 자체 LICENSE 파일 없음, NanumGothic OFL 원문 미동봉 |
§6 |
| A-4 | 자동 판정 테스트 없음, e2e 고장 | §3.3 |
| A-5 | Fit 이 가장자리를 잘라냄 | §3.4-① |
| A-6 | 미커밋 WIP 정리, src/topProgress.ts 어디서도 import 되지 않음, 루트 대용량 untracked 파일 |
git status |
| A-7 | 원본 hmwebviewer 에 Model/Paper 수정 미이식 (cadSpaces.ts 없음) |
model-paper-space.md §9 |
B. 기능·품질
| # | 과제 | 근거 |
|---|---|---|
| B-1 | 해치 손상 호의 근본 원인 미확인. 현재 수정은 감지 후 생략. spurious_r 5배 임계값은 경험값 |
hatch-boundary-arc-artifact.md §7 |
| B-2 | 파싱 중 메인 스레드 블로킹. 37MB 도면 로드 5.5초 동안 UI 정지. Web Worker 미적용 | 이번 측정 |
| B-3 | 메쉬 레이어에 굵기가 지정되면 fat 버킷 상한(40만) 124.5% 초과 → 버킷 전체 헤어라인 폴백 | improvement-results §5-3 |
| B-4 | %%% 등 제어코드, CP949 기호 |
§3.4-②③ |
| B-5 | tables.styles 비어 있음 → 폰트 매핑 불가 |
한글 문서 §8, 이번 e2e |
| B-6 | 한글 처리가 JS 휴리스틱. 932/936/950 미지원 | 한글 문서 §8 |
| B-7 | Layout 탭 캡션이 내부명 | 이번 실행 |
| B-8 | acadrust notification 내용 비노출 | 이번 실행 |
| B-9 | 40만 상한 초과 시 사용자 알림 없음 (console.warn 만) |
lineweight-rendering.md §6 |
| B-10 | wasm32 4GB 한계. 37MB 도면에서 Node RSS 1.37GB, 브라우저 JS heap 782MB | 이번 측정 |
C. 나중에
- 선가중치: 중첩 ByBlock 미추적, DXF LAYER 코드 370 무시,
celweight가 DWG 인덱스 그대로 나감 - MESH: Catmull-Clark(
subdivisionLevel > 0), POLYFACE/POLYGON MESH, shaded 패스 - VIEWPORT: 솔리드 HATCH 근사, 비직교 VP, TILEMODE/CTAB 휴리스틱
- OLE BMP 가 24/32bpp 만 지원
parse_dwgexport 미정리- CXGLOGO-EX흑백.dwg 의 얇은 원 (hmwebviewer 시절부터)
D. 배포·문서 정리
build:dist2스크립트 없음,dist2/assets에 예전 해시 번들 누적, 테스트 도면이dist2/samples에 섞여 있음- 문서 상태 표기가 낡음:
subdmesh-rendering.md: "렌더러 미커밋"lineweight-rendering.md,improvement-results: "미푸시"- 여러 문서: "acadrust 미수정"
Viewer2D.d.ts:24,Viewer2D.js:1389주석은 "Default 20" 인데 실제 기본값은 11- README 이슈 표에 hatch, large-dwg 문서 누락
6. 라이브러리 배포 가능성
6.1 결론: 조건부 가능
- 파서는 DOM 없이 동작한다. Node 24 에서
initSync로 19개 도면을 파싱해 실측했다. - Viewer2D 가 DOM 에 닿는 곳은 생성자로 받는
container하나뿐이다. - 다만 아래 차단 요소를 먼저 풀어야 한다.
6.2 차단 요소
| # | 문제 | 위치 | 영향 |
|---|---|---|---|
| L1 | MPL 패치로 소스 재현 불가 | §5 A-1 | 법적 의무 미충족 |
| L2 | Visio 저작권 lin 데이터 | linData.ts:2 |
재배포 권리 확인 필요 |
| L3 | 자체 LICENSE, package.json license 필드 없음. Viewer2D.js:3 에 "Ported from webviewer/…" |
루트 | 사용 권리 불명확 |
| L4 | NanumGothic OFL 원문 미동봉 | public/licenses/ |
폰트 동봉 시 위반 |
| B1 | ?url import 가 Vite 전용 |
acadrustParser.ts:6 |
Node·webpack·SSR 에서 실패. Vite lib 모드로 빌드하면 wasm 이 base64 로 두 번 인라인됨 (실측 2.37MB) |
| B2 | 확장자 없는 상대 import | dwgParser.ts:16, parseDxf.ts:7, Viewer2D.js:16-18 외 |
Node ESM 에서 ERR_MODULE_NOT_FOUND (§3.3 과 같은 원인) |
| B3 | 폰트 경로 /fonts/… 하드코딩, 전역 싱글톤 |
slugText.ts:32-49, Viewer2D.js:127 |
호스트에 그 경로가 없으면 404 |
| B4 | dispose() 없음 |
Viewer2D.js:159,164,4527 |
익명 window 리스너와 rAF 루프를 해제할 수 없음. F 키 리스너는 입력란에서도 Fit 실행 |
| B5 | 타입 불완전 | Viewer2D.d.ts |
load(result: unknown), 일부 메서드 누락, 기본값 주석 20 ≠ 실제 11 |
| B6 | 패키지 설정 없음 | package.json |
private: true, exports/files/peerDependencies 없음 |
| B7 | 소스 정본이 여러 곳 | 이 레포 / hmwebviewer/src/viewer2d / hmwebviewer/packages/dwg-dxf-viewer |
wasm 바이너리 3개가 모두 다름. Viewer2D.js 는 hmwebviewer 와 1,217줄 차이 |
6.3 권장 구조: 패키지 2개
@scope/cad-parser (headless, three 없음) license: "MIT AND MPL-2.0"
initDwgParser({ wasm?: URL | bytes | Module })
parseDwg(bytes) / parseDxf(buf) / parseCad(buf, nameHint?)
listCadSpaces, pickDefaultSpace, isDwg/isDxf, CadParseResult 타입
./worker (선택: 메인 스레드 비블로킹)
@scope/viewer2d (Viewer2D, slugText, linParser) license: "MIT"
peerDependencies: three ^0.185.0 ← peer + external
dependencies: @scope/cad-parser, opentype.js
파서 패키지 package.json 핵심:
{
"type": "module",
"license": "MIT AND MPL-2.0",
"exports": {
".": { "types": "./dist/index.d.ts", "node": "./dist/node.js", "default": "./dist/browser.js" },
"./worker": "./dist/worker.js",
"./acadrust_dwg_bg.wasm": "./dist/acadrust_dwg_bg.wasm"
},
"files": ["dist", "licenses", "THIRD-PARTY-NOTICES.md", "LICENSE"],
"sideEffects": false
}
wasm 로딩:
- 기본: glue 의
new URL('./acadrust_dwg_bg.wasm', import.meta.url)패턴을 유지한다. - 탈출구:
init({ wasm })로 URL, bytes, Module 을 직접 넘길 수 있게 한다. - Node:
initSync({ module: readFileSync(...) }).scripts/parse-dwg.mjs에서 동작을 확인했다.
6.4 작업 순서
- 라이선스 L1~L4 해결
- 정본 레포 통일,
rust/dwg-wasm과 vendored acadrust 이전,rust-toolchain.toml로 툴체인 고정 - 파서 분리:
?url제거,init({ wasm })추가, Node 진입점,parseCad(), 상대 import 에.js - Viewer2D: 생성자 옵션(
fontUrl,keyboard등),dispose(),ResizeObserver,localStorage잔재 제거, 콜백 해제 함수 - 타입: 수기
Viewer2D.d.ts보완,CadParseResult구체화 - 빌드: tsup/rollup/tsc 로 ESM, wasm 은 파일로 복사,
opentype.js는 default import (Node ESM 에서 named import 실패 실측) - 검증: 소비 예제(Vite, webpack 5, Node)를 CI 로 돌리고, §3 의 샘플 20개 e2e 를 회귀 테스트로
6.5 유의할 점
-
크기
파일 raw brotli wasm 884KB 301KB 폰트 2.05MB 432KB 폰트는 번들하지 말고
fontUrl옵션으로 받는다. -
메모리: 37MB 도면에서 Node RSS 1.37GB, 브라우저 JS heap 782MB. wasm32 상한은 4GB 다.
-
런타임: CSP 에
'wasm-unsafe-eval'이 필요하다.application/wasmMIME 이 아니면 느린 폴백으로 떨어진다. -
한글:
cp949/euc-krTextDecoder 가 없는 런타임에서는fixDwgKoreanText가 아무 표시 없이 보정을 건너뛴다. -
버전 정책: 두 패키지는 lockstep 으로 올린다.
CadParseResult필드 추가는 minor, 삭제나 변경은 major. -
upstream drift: README 의 "본가에서 다시 복사" 절차를 따르면 이 레포의 기능(lineweight, 2.5D, Model/Layout)이 지워진다.
-
acadrust 버전: 상류는 0.6.x 다. 0.4.1 fork 유지 여부를 결정해야 한다.
-
릴리스: 깨끗한 태그에서만 배포한다.
7. 재현 방법
# 헤드리스 파싱 (1개 파일)
node scripts/parse-dwg.mjs "<file.dwg>" [out.json]
# 기존 e2e (현재는 실패, §3.3)
node e2e_lin_test.cjs
배치 파서, 브라우저 e2e, 3단 비교 캡처 스크립트는 세션 임시 폴더에 있다. 레포 반영은 §2-3. 측정 원본은 images/sample-test-2026-10-19/results.json 에 있다.
8. 검증 불가 목록
| 항목 | 이유 |
|---|---|
| OLE BMP(#3), OLE2FRAME(#4) | OLE2FRAME 엔티티가 있는 샘플이 없음 |
| 선가중치 배율(#11)이 AutoCAD 와 일치하는지 | 같은 위치의 AutoCAD 정답 캡처가 없음 |
| 한글 깨짐(#1) 수정 전 화면 | 같은 커밋에서 고친 '글자 거대' 버그 때문에 판독 불가. 문자열 비교로 대신 검증함 |
| 수정 전 수치와 문서 기록의 차이 (로드 213.8s vs 문서 354s, 토글 약 0.5s vs 커밋 "5초 이상") | 당시 측정 환경과 방법을 알 수 없음 |
| Fit 잘림의 원인 | 재현만 확인, 원인 미확정 |
H-DICHL06 의 patternLen(1) 과 요소 합(1.588) 중 어느 쪽이 AutoCAD 기준인지 |
AutoCAD 대조 수단 없음 |
문서상 한글 재현 도면 C0060203-002-굴착및시공순서도.dwg |
레포에 없음 |
| 7~8월 테스트 당시의 증상 원문 | 세션 기록이 남아 있지 않음 (가장 오래된 기록이 09-16) |



















