diff --git a/README.md b/README.md index 618debb..8df4d51 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ Vite `?url` import 로 로드됩니다. | SubDMesh(MESH) 미표시 — parseResult 누락 + 큰 메쉬 잘림 | [`docs/subdmesh-rendering.md`](./docs/subdmesh-rendering.md) | | 선가중치(Lineweight) 미적용 — parseResult 누락 + WebGL 1px 한계 | [`docs/lineweight-rendering.md`](./docs/lineweight-rendering.md) | | acadrust MPL-2.0 고지 누락 (수정본 wasm 공개 배포) | [`docs/license-mpl2-acadrust.md`](./docs/license-mpl2-acadrust.md) | +| acadrust 0.6.5 무수정 전환 — strict 파싱 실패, memory.grow 지연, VIEWPORT id | [`docs/acadrust-0.6.5-upgrade.md`](./docs/acadrust-0.6.5-upgrade.md) · 캡처 비교 [`report.html`](./docs/acadrust-0.6.5-upgrade-report.html) | | ↳ 위 둘의 측정 결과 + 상호작용(메쉬 선분이 굵기 버킷 상한을 넘길 위험) | [`docs/improvement-results-2026-08-04.md`](./docs/improvement-results-2026-08-04.md) | 샘플 패치: `fixDwgKoreanText`, `cadSpaces` + Viewer2D 공간 필터, Model/Layout 탭. @@ -125,11 +126,12 @@ Vite `?url` import 로 로드됩니다. | 조각 | 라이선스 | |------|----------| | Viewer2D 포트 · 샘플 글루 | MIT (hmwebviewer 계열) | -| acadrust (WASM 내부, `read_mesh` 로컬 패치 포함) | **MPL-2.0 — 수정본** | +| acadrust 0.6.5 (WASM 내부, crates.io 무수정) | **MPL-2.0** | | dxf-parser · three · opentype.js | MIT | | NanumGothic | OFL | -acadrust 는 파일 단위 카피레프트라 **패치한 파일의 소스를 배포 대상자에게 제공할 의무**가 -있다. 고지·MPL 원문·패치는 [`THIRD-PARTY-NOTICES.md`](./THIRD-PARTY-NOTICES.md) 와 -`public/licenses/`(배포 시 `/licenses/`)에 동봉한다. +acadrust 는 무수정으로 쓰므로 **MPL 원문 동봉 + 소스 입수 위치 고지**만 하면 된다. +고지와 MPL 원문은 [`THIRD-PARTY-NOTICES.md`](./THIRD-PARTY-NOTICES.md) 와 +`public/licenses/`(배포 시 `/licenses/`)에 동봉한다. 0.4.1 패치본에서 옮겨 온 경위: +[`docs/acadrust-0.6.5-upgrade.md`](./docs/acadrust-0.6.5-upgrade.md) 의무 범위와 조치 근거: [`docs/license-mpl2-acadrust.md`](./docs/license-mpl2-acadrust.md) diff --git a/docs/acadrust-0.6.5-upgrade-report.html b/docs/acadrust-0.6.5-upgrade-report.html new file mode 100644 index 0000000..815618b --- /dev/null +++ b/docs/acadrust-0.6.5-upgrade-report.html @@ -0,0 +1,299 @@ + + + + + +acadrust 업그레이드 보고서 + + + +
+
+

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 / 22양쪽 모두 정상 로드
+
17 / 22기본 화면 픽셀 동일
+
5화면이 달라진 샘플 — 전부 개선
+
0콘솔 에러 (양쪽)
+
+ + +

2. 비교 방법

+ + +

3. 전체 결과

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
#파일위치MB기본 탭엔티티로드 0.4.1 → 0.6.5화면 차이판정
1BasicSample.dwgpublic/samples0.4Model7,309394 → 435 ms0 %동일
2C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwgpublic/samples5.4Layout17,810958 → 987 ms0 %동일
3C0060203-001-표준단면도(2차로,자연환기300m이상).dwgpublic/samples0.4Model2,068347 → 412 ms0 %동일
4C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwgpublic/samples0.8Model5,979314 → 356 ms0.02 %개선
5bb.dwgpublic/samples0.7Layout438231 → 307 ms0 %동일
6dwg_1.60mb.dwgpublic/samples1.6Model21,3301,139 → 1,253 ms0.0089 %개선
7dwg_18.3mb.dwgpublic/samples18.4Model82,3933,920 → 4,024 ms0 %동일
8simple.dxfpublic/samples0.0—655 → 54 ms0 %동일
904manhole1-simplify.dwgdist2/samples0.4Layout7,035357 → 421 ms0 %동일
10대산당진 2공구_노면_20260804_143854.dwgdist2/samples37.1Model65,4955,651 → 5,737 ms0 %동일
11test.dwgdist2/samples18.4Model82,3933,719 → 4,043 ms0 %동일
12a. 거더배치 삽도_25.02.28.dwgdwg2model0.2Layout1,433453 → 484 ms0 %동일
13a. 교대배치 삽도_25.02.28.dwgdwg2model0.4Layout2,138320 → 293 ms0 %동일
14a. 교량시종점 삽도_25.02.28.dwgdwg2model0.4Layout4,432377 → 353 ms3.45 %개선
15a. 교량폭원 삽도_25.02.28.dwgdwg2model0.5Layout2,824210 → 258 ms0 %동일
16a. 교면포장 삽도_25.02.28.dwgdwg2model0.2Layout1,304176 → 226 ms0 %동일
17a. 중앙분리대 삽도_25.02.28.dwgdwg2model0.4Layout2,159267 → 260 ms18.37 %개선
18a. 횡단경사 삽도_25.02.28.dwgdwg2model0.5Layout5,635343 → 341 ms0 %동일
19산외교- ELEVATION 산출근거도 (울산방향).dwgdwg2model0.6Model11,262740 → 818 ms0.0047 %개선
20산외교-받침배치도 (울산방향) .dwgdwg2model0.4Model6,240590 → 689 ms0 %동일
21산외교_파이형_교각일반도(울산P11-꺾임).dwgdwg2model1.0Model25,927707 → 731 ms0 %동일
22산외교_파이형_교각일반도(울산P9).dwgdwg2model1.0Model26,207732 → 710 ms0 %동일
+

로드 시간은 파일 선택부터 상태바 ✓ 표시까지(파싱 + 렌더). 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 무수정
MESH(SubDMesh) — 노면·부체도로면 삼각망 0.4.1MESH(SubDMesh) — 노면·부체도로면 삼각망 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 무수정
OLE2FRAME — 삽입 이미지와 위치 0.4.1OLE2FRAME — 삽입 이미지와 위치 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.10.6.5차이
a. 중앙분리대 삽도_25.02.28.dwg 0.4.1a. 중앙분리대 삽도_25.02.28.dwg 0.6.5a. 중앙분리대 삽도_25.02.28.dwg 차이
+

a. 교량시종점 삽도_25.02.28.dwg

+

개선 트루컬러 해치(RGB 128,93,59)의 근사 색이 ACI 35 → 37 로 바뀌어 원본에 더 가까워짐 · 기본 화면 차이 3.45 % · 확대 화면 차이 7.80 %

+
+ + +
0.4.10.6.5차이
a. 교량시종점 삽도_25.02.28.dwg 0.4.1a. 교량시종점 삽도_25.02.28.dwg 0.6.5a. 교량시종점 삽도_25.02.28.dwg 차이
a. 교량시종점 삽도_25.02.28.dwg 확대 0.4.1a. 교량시종점 삽도_25.02.28.dwg 확대 0.6.5a. 교량시종점 삽도_25.02.28.dwg 확대 차이
+

C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg

+

개선 ATTDEF 정렬을 새로 읽어 동그라미 번호(①)가 원의 오른쪽 아래에서 중앙으로 옮겨짐 · 기본 화면 차이 0.02 % · 확대 화면 차이 0.02 %

+
+ + +
0.4.10.6.5차이
C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 0.4.1C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 0.6.5C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 차이
C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 확대 0.4.1C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 확대 0.6.5C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 확대 차이
+

dwg_1.60mb.dwg

+

개선 3D 폴리선 vertex 순서 수정 — 곡선을 가로지르던 가짜 직선(청록)이 사라짐 · 기본 화면 차이 0.0089 % · 확대 화면 차이 0.48 %

+
+ + +
0.4.10.6.5차이
dwg_1.60mb.dwg 0.4.1dwg_1.60mb.dwg 0.6.5dwg_1.60mb.dwg 차이
dwg_1.60mb.dwg 확대 0.4.1dwg_1.60mb.dwg 확대 0.6.5dwg_1.60mb.dwg 확대 차이
+

산외교- ELEVATION 산출근거도 (울산방향).dwg

+

개선 작은 표고 텍스트 2곳의 위치 (ATTDEF 정렬) · 기본 화면 차이 0.0047 %

+
+ + +
0.4.10.6.5차이
산외교- ELEVATION 산출근거도 (울산방향).dwg 0.4.1산외교- ELEVATION 산출근거도 (울산방향).dwg 0.6.5산외교- ELEVATION 산출근거도 (울산방향).dwg 차이
+ +

6. 전체 샘플 화면 비교 (기본 화면)

+

파일을 열었을 때 처음 보이는 화면이다. 이미지를 누르면 크게 볼 수 있다.

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
파일0.4.10.6.5
1. BasicSample.dwg
Model · 7,309 엔티티
픽셀 동일
BasicSample.dwg 0.4.1BasicSample.dwg 0.6.5
2. C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwg
Layout · 17,810 엔티티
픽셀 동일
C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwg 0.4.1C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwg 0.6.5
3. C0060203-001-표준단면도(2차로,자연환기300m이상).dwg
Model · 2,068 엔티티
픽셀 동일
C0060203-001-표준단면도(2차로,자연환기300m이상).dwg 0.4.1C0060203-001-표준단면도(2차로,자연환기300m이상).dwg 0.6.5
4. C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg
Model · 5,979 엔티티
개선 · 0.02 %
§5 참고
C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 0.4.1C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 0.6.5
5. bb.dwg
Layout · 438 엔티티
픽셀 동일
bb.dwg 0.4.1bb.dwg 0.6.5
6. dwg_1.60mb.dwg
Model · 21,330 엔티티
개선 · 0.0089 %
§5 참고
dwg_1.60mb.dwg 0.4.1dwg_1.60mb.dwg 0.6.5
7. dwg_18.3mb.dwg
Model · 82,393 엔티티
픽셀 동일
dwg_18.3mb.dwg 0.4.1dwg_18.3mb.dwg 0.6.5
8. simple.dxf
— · 6 엔티티
픽셀 동일
simple.dxf 0.4.1simple.dxf 0.6.5
9. 04manhole1-simplify.dwg
Layout · 7,035 엔티티
픽셀 동일
04manhole1-simplify.dwg 0.4.104manhole1-simplify.dwg 0.6.5
10. 대산당진 2공구_노면_20260804_143854.dwg
Model · 65,495 엔티티
픽셀 동일
대산당진 2공구_노면_20260804_143854.dwg 0.4.1대산당진 2공구_노면_20260804_143854.dwg 0.6.5
11. test.dwg
Model · 82,393 엔티티
픽셀 동일
test.dwg 0.4.1test.dwg 0.6.5
12. a. 거더배치 삽도_25.02.28.dwg
Layout · 1,433 엔티티
픽셀 동일
a. 거더배치 삽도_25.02.28.dwg 0.4.1a. 거더배치 삽도_25.02.28.dwg 0.6.5
13. a. 교대배치 삽도_25.02.28.dwg
Layout · 2,138 엔티티
픽셀 동일
a. 교대배치 삽도_25.02.28.dwg 0.4.1a. 교대배치 삽도_25.02.28.dwg 0.6.5
14. a. 교량시종점 삽도_25.02.28.dwg
Layout · 4,432 엔티티
개선 · 3.45 %
§5 참고
a. 교량시종점 삽도_25.02.28.dwg 0.4.1a. 교량시종점 삽도_25.02.28.dwg 0.6.5
15. a. 교량폭원 삽도_25.02.28.dwg
Layout · 2,824 엔티티
픽셀 동일
a. 교량폭원 삽도_25.02.28.dwg 0.4.1a. 교량폭원 삽도_25.02.28.dwg 0.6.5
16. a. 교면포장 삽도_25.02.28.dwg
Layout · 1,304 엔티티
픽셀 동일
a. 교면포장 삽도_25.02.28.dwg 0.4.1a. 교면포장 삽도_25.02.28.dwg 0.6.5
17. a. 중앙분리대 삽도_25.02.28.dwg
Layout · 2,159 엔티티
개선 · 18.37 %
§5 참고
a. 중앙분리대 삽도_25.02.28.dwg 0.4.1a. 중앙분리대 삽도_25.02.28.dwg 0.6.5
18. a. 횡단경사 삽도_25.02.28.dwg
Layout · 5,635 엔티티
픽셀 동일
a. 횡단경사 삽도_25.02.28.dwg 0.4.1a. 횡단경사 삽도_25.02.28.dwg 0.6.5
19. 산외교- ELEVATION 산출근거도 (울산방향).dwg
Model · 11,262 엔티티
개선 · 0.0047 %
§5 참고
산외교- ELEVATION 산출근거도 (울산방향).dwg 0.4.1산외교- ELEVATION 산출근거도 (울산방향).dwg 0.6.5
20. 산외교-받침배치도 (울산방향) .dwg
Model · 6,240 엔티티
픽셀 동일
산외교-받침배치도 (울산방향) .dwg 0.4.1산외교-받침배치도 (울산방향) .dwg 0.6.5
21. 산외교_파이형_교각일반도(울산P11-꺾임).dwg
Model · 25,927 엔티티
픽셀 동일
산외교_파이형_교각일반도(울산P11-꺾임).dwg 0.4.1산외교_파이형_교각일반도(울산P11-꺾임).dwg 0.6.5
22. 산외교_파이형_교각일반도(울산P9).dwg
Model · 26,207 엔티티
픽셀 동일
산외교_파이형_교각일반도(울산P9).dwg 0.4.1산외교_파이형_교각일반도(울산P9).dwg 0.6.5
+ +

7. 파싱 데이터 비교

+

Node 에서 두 wasm 으로 같은 DWG 21개를 파싱해 엔티티를 타입#handle 로 짝지은 뒤 필드별로 비교했다. 파일별 엔티티 수와 handle 집합은 완전히 같고, 값이 바뀐 필드는 아래가 전부다.

+
+ + + + + + + + + + + +
바뀐 값필드 변경 건수파일 수원인화면 영향
치수 정의점 pt101,175120.4.1 이 (0,0,0) 으로 냄 → 실제 좌표블록 없는 치수(대체 렌더)의 선택 범위·extents 만
ATTDEF 정렬점·정렬·폭 비율2,171140.4.1 이 읽지 못함 → 실제 값블록 안 속성 텍스트 위치·폭이 정확해짐
익명 블록 이름8121번호 체계 변경 (*U1 → *U7)없음 — 렌더는 handle 기준, 이름·블록 테이블 불일치 0건
트루컬러 엔티티의 근사 ACI1163근사 계산 개선 (원본 RGB 는 동일)원본 색에 더 가까워짐
VIEWPORT id 0 → 127100.6.5 가 레이아웃 전체 뷰포트에 id 1 부여전체 뷰포트 오판 해소 (중앙분리대 검은 띠)
VIEWPORT 상태 비트262비트 0x10000 추가없음 (Viewer2D 는 isOn 만 사용)
3D 폴리선 점 순서710.4.1 이 vertex 를 handle 순으로 정렬가짜 직선 제거 (dwg_1.60mb)
텍스트 내용11CP949 기호 디코딩 (500¡¿350 → 500×350)깨진 기호 1건 해소
OLE 데이터 길이11페이로드 재조립으로 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 KB2,976 KB / 815 KB
브라우저 로드 — 대산당진 노면 (37 MB)5,651 → 5,737 ms
브라우저 로드 — dwg_18.3mb (18 MB)3,920 → 4,024 ms
Node 파싱만 — 노면 / dwg_18.3mb3.0 s / 1.9 s3.3 s / 2.1 s
wasm 메모리 — 노면 / dwg_18.3mb672 / 546 MB773 / 505 MB
+

크기가 커진 것은 acadrust 0.6 이 DXF/DWG 쓰기, ACIS 등을 포함해 라이브러리 자체가 커졌기 때문이다. 끌 수 있는 기능 옵션은 없다. 크기 우선 최적화(opt-level = "z")도 시험했으나 815 → 742 KB(−9 %)를 얻는 대신 파싱이 36 % 느려져 채택하지 않았다.

+ +

10. 라이선스 영향

+ + +

11. 남은 것

+ +

검증하지 못한 것

+
+ + + +
항목이유
AutoCAD 원본 화면과의 대조같은 위치의 AutoCAD 정답 캡처가 없다. 개선 판정은 데이터 근거(원본 RGB, vertex 좌표의 연속성, 뷰포트 id·배율)에 기댄다
Firefox / Safari 에서의 로드 시간Chrome 과 Node 에서만 측정
Layout/Model 탭을 바꾼 뒤의 화면, 2.5D 보기기본 화면과 지정 확대 화면만 캡처
+
+ + + + diff --git a/docs/acadrust-0.6.5-upgrade.md b/docs/acadrust-0.6.5-upgrade.md new file mode 100644 index 0000000..d72a8cd --- /dev/null +++ b/docs/acadrust-0.6.5-upgrade.md @@ -0,0 +1,115 @@ +# acadrust 0.4.1(패치) → 0.6.5(무수정) 업그레이드 + +| 항목 | 내용 | +|------|------| +| 날짜 | 2026-10-19 | +| 목적 | 로컬 패치를 없애 MPL-2.0 의무를 "고지 + 소스 링크"로 줄인다 ([`license-mpl2-acadrust.md`](./license-mpl2-acadrust.md)) | +| Rust 쪽 변경 | `hmwebviewer` 브랜치 `chore/acadrust-0.6.5` (`feat/subdmesh-render` 에서 분기) | +| 이 레포 변경 | `src/viewer2d/acadrust-dwg/` wasm 교체, 고지·문서 갱신 | +| 상태 | 수정 완료·검증됨 (샘플 20개 파싱 비교 + 브라우저 로드·스크린샷) | +| 캡처 보고서 | [`acadrust-0.6.5-upgrade-report.html`](./acadrust-0.6.5-upgrade-report.html) — 샘플 22개 기존/신규 화면 비교 (이미지 내장) | + +--- + +## 1. 결론 + +- acadrust 를 고치지 않고도 기존 두 수정(MESH, OLE2FRAME)의 결과가 그대로 나온다. +- 화면 회귀는 없다. 패널을 숨기고 도면만 찍은 최종 캡처 기준으로, 샘플 22개 중 17개는 기본 화면이 픽셀 단위로 같다. 나머지 5개의 차이는 모두 데이터가 더 정확해진 결과다 (§4, [캡처 보고서](./acadrust-0.6.5-upgrade-report.html)). §4 의 스크린샷 표는 툴바가 함께 찍힌 첫 캡처 기준이라 탭 이름 차이가 섞여 있다. +- 대가: wasm 이 커졌고 (brotli 294 → 815 KB), 대형 도면 파싱이 10~16% 느려졌다 (§5). + +## 2. dwg-wasm 변경 (우리 MIT 코드) + +| 변경 | 이유 | +|---|---| +| `acadrust = "=0.6.5"` (crates.io, 정확한 버전 고정), vendored `rust/acadrust/` 삭제 | 무수정 사용. 고지에 적은 버전과 빌드 소스를 일치시킨다 | +| `match d.as_ref()` | 0.6 에서 `EntityType::Dimension` 이 `Box` 으로 바뀜 | +| `DIMENSION_ARC`, `DIMENSION_LARGE_RADIAL` 타입명 추가 | 0.6 이 새로 읽는 치수. 0.4 는 버렸고, Viewer2D 는 아직 이 이름을 그리지 않으므로 화면은 전과 같다 | +| OLE: `o.binary_data` → `o.encoded_payload()` | 0.6 은 OLE 페이로드를 envelope + compound file 로 분해해 둔다. 재조립한 바이트로 기존 DIB 탐색을 한다. 추출 이미지는 기존과 바이트 단위로 같다 | +| `DwgReadOptions::failsafe()` | 0.6 strict 모드는 레코드 하나가 깨져도 도면 전체를 거부한다. `a. 거더배치 삽도` 가 handle 0x2663(type 37)의 잘못된 배열 개수로 통째로 실패했다. failsafe 에서는 정상 로드되고, 건너뛴 레코드는 notifications 로 간다 | +| 전역 할당자: dlmalloc 을 32 MiB 단위로 확장 | 아래 §2.1 | + +### 2.1 wasm 메모리 확장 비용 + +0.6.5 를 그대로 올리면 37 MB 노면 도면 파싱이 Node 에서 3.0초 → 7.4초로 느려졌다. + +- **원인 확정** (CPU 프로파일): 시간의 55% 가 `::alloc`, 즉 wasm `memory.grow` 에 있었다. +- V8 에서 `memory.grow` 한 번의 비용은 늘리는 양이 아니라 **현재 메모리 크기**에 비례한다 (Node 24 실측: 16 MB 일 때 0.04 ms, 700 MB 일 때 1.6 ms). +- 0.6 은 짧게 쓰고 버리는 버퍼가 많아서, 기본 dlmalloc(64 KB 페이지 단위)이 수천 번 확장했다. + +`dwg-wasm/src/lib.rs` 의 `big_step_alloc` 이 같은 dlmalloc 을 `set_granularity(32 MiB)` 로 감싸서 해결한다. acadrust 는 건드리지 않는다. 결과는 7.4초 → 3.3초. 대신 힙 끝에 최대 한 단계(32 MB)가 비어 있을 수 있다. + +## 3. 검증 방법 + +1. **파싱 비교 (Node)**: 기존 wasm 과 새 wasm 으로 같은 DWG 19개를 파싱한다. `fixDwgKoreanText` 까지 적용한 뒤, 엔티티를 `타입#handle` 로 짝짓는다. 필드마다 정규화(숫자 12자리)한 해시로 비교했다. +2. **브라우저 (Chrome headless, 실 GPU)**: 같은 작업 트리에서 wasm 만 바꿔 20개(DWG 19 + DXF 1)를 로드한다. 상태바 `✓` 판정, 콘솔 에러, 1280×800 스크린샷 픽셀 비교를 했다. +3. **네이티브 프로브**: MESH/OLE2FRAME 값을 원본 0.4.1 · 패치본 · 0.6.5 로 비교했다 ([`license-mpl2-acadrust.md`](./license-mpl2-acadrust.md) §3). + +## 4. 결과 + +**파싱**: 19/19 성공. 파일별 엔티티 수와 handle 집합이 완전히 같다 (354,502개 중 누락·추가 0). 필드 값이 바뀐 엔티티는 2,815개(0.79%)다. + +| 바뀐 필드 | 건수 / 파일 | 원인 | 화면 영향 | +|---|---|---|---| +| `DIMENSION_*.pt10` | 1,168 / 9 | 0.4.1 이 정의점을 (0,0,0) 으로 냈다 → 실제 좌표 | 블록 없는 치수(fallback)의 선택 범위·extents 만 | +| `ATTDEF` alignmentPt / horiz·vertAlignment / widthFactor | 최대 664 / 13 | 0.4.1 이 읽지 못했다 → 실제 값 | 블록 안 ATTDEF 텍스트 위치·폭이 정확해진다 | +| `INSERT.blockName`, `tables.blocks` 이름 | 812 / 1 (ELEVATION) | 익명 블록 번호 체계가 바뀜 (`*U1` → `*U7`) | 없음. 렌더는 handle 기준이고, INSERT 이름과 블록 테이블 이름은 전 파일에서 일치(불일치 0) | +| `entityHeader.colorIndex` (트루컬러 엔티티) | 116 / 3 | 트루컬러 → 가장 가까운 ACI 근사가 개선됨. 원본 RGB 는 같다 | 원본 RGB 에 더 가까운 색 (Viewer2D 팔레트 기준 거리 130.8→117.6, 51.5→24.7) | +| `VIEWPORT.id` 0 → 1 | 27 / 10 | 0.6.5 가 레이아웃의 전체(paper) 뷰포트에 id 1 을 준다 | 7개 파일에서 전체 뷰포트를 모델 창으로 오판하던 것이 사라졌다 (아래) | +| `VIEWPORT.status.bits` | 26 / 2 | 비트 0x10000 추가 | 없음 (Viewer2D 는 `isOn` 만 사용) | +| `TEXT.text` | 1 / 1 | `500¡¿350` → `500×350` | CP949 기호 깨짐 1건 해소 | +| `OLE2FRAME.dataLength` | 1 / 1 | 페이로드 재조립으로 512 B 차이 | 없음 (이미지 바이트 동일) | +| `vars.celweight` | 전 파일 | 29 → -1 | 없음 (미사용) | + +**VIEWPORT 판정**: id 가 1 로 바뀐 VP 는 모두 레이아웃마다 하나뿐인 전체 뷰포트였다 (배율 1.0000, target (0,0)). 진짜 모델 창(id ≥ 2)의 판정은 전 파일에서 그대로다. + +기존에는 `Viewer2D._isModelViewport` 의 휴리스틱이 이 VP 를 모델 창으로 오판했다. 판정 조건 중 "viewCenter ≈ center" 가 맞지 않았기 때문이다. 그래서 모델 공간을 레이아웃 위에 한 번 더 투영했다. `a. 중앙분리대 삽도` 의 기본 화면을 가로지르던 검은 세로 띠가 이것이고, 업그레이드 후 사라졌으며 Fit 도 도면을 제대로 채운다. + +**브라우저**: 기존·신규 모두 20/20 로드 성공. 기본 탭(Model/Layout) 동일, 콘솔 에러 동일 (첫 페이지 favicon 404 1건). + +| 스크린샷 차이 | 파일 | 내용 | +|---|---|---| +| 0% (픽셀 동일) | 16개 | — | +| 16.9% | a. 중앙분리대 삽도 | 검은 띠 제거, Fit 개선, 해치 갈색이 원본 RGB 에 가까워짐 | +| 3.3% / 0.5% | a. 교량시종점 / a. 횡단경사 | 트루컬러 근사색 | +| 0.6% / 0.005% | a. 교량폭원 / ELEVATION | 툴바의 Layout 탭 이름 폭 | + +Layout 탭 이름은 익명 paper 블록 번호를 따르므로 바뀌었다 (`Paper_Space1` → `Paper_Space194` 등). 원래 내부 이름이 보이던 문제(레이아웃 실제 이름 미사용)는 그대로다. + +notification 수는 4개 파일에서 늘었다 (BasicSample 4→24, 거더배치 5→11 등). 0.6.5 가 진단을 더 많이 남기는 것이다. + +### 4.1 추가 샘플 (`public/samples/` 신규 3개) + +`dwg_18.3mb.dwg` 는 `dist2/samples` 의 같은 파일(md5 동일)이라, 실제 신규는 2개다: +`C0060203-002-굴착및시공순서도`, `dwg_1.60mb.dwg`. + +- 3개 모두 기존·신규 파싱 성공이다. 0.6.5 strict 모드에서도 실패하지 않는다. 엔티티 수와 handle 집합이 같고, 브라우저 로드 성공, 콘솔 에러 0이다. +- **3D 폴리선 vertex 순서** (`dwg_1.60mb`, 옹벽·관로 7개, `원인 확정`). + - 두 버전 모두 vertex 13개는 같고 순서만 다르다. + - 0.4.1 은 vertex 를 handle 번호 순으로 정렬했다. 그래서 나중에 추가된 vertex(handle 227026, 가장 서쪽 점)가 중간에 끼어들어, 선이 최대 193 단위 되돌아갔다 오는 가짜 현(chord)이 생겼다. + - 0.6.5 는 DWG 연결 순서를 따른다 (x 가 단조 증가하는 매끈한 선). 확대 캡처에서 곡선을 가로지르던 청록 직선이 사라진 것을 확인했다. +- **ATTDEF 정렬**: 굴착및시공순서도의 동그라미 번호가 원의 아래쪽에서 중앙으로 옮겨졌다 (§4 의 ATTDEF 행과 같은 원인). +- **한글**: 0.6.5 는 CP949 를 원본에서 직접 디코딩한다. + - 기존 wasm 은 평면및종단면도(153개)와 굴착및시공순서도(160개)를 Latin-1 로 깨진 채 내보냈고, `fixDwgKoreanText` 가 복원해 왔다. + - 0.6.5 는 21개 DWG 전부 원본 깨짐 0이다. 보정 후 한글 텍스트 수는 전 파일에서 같다. + - `fixDwgKoreanText` 는 이 샘플들에서 할 일이 없어졌다. 다른 코드페이지 도면 대비용 안전망으로 남겨 둔다. + +## 5. 비용 + +| 항목 | 0.4.1 패치본 | 0.6.5 | +|---|---|---| +| wasm raw / brotli | 864 KB / 294 KB | 2,976 KB / 815 KB | +| 노면 37 MB 파싱 (Node) | 3.0 s | 3.3~3.5 s | +| dwg_18.3mb 파싱 (Node) | 1.9 s | 2.1 s | +| 노면 브라우저 로드 | 5.4 s | 5.7 s | +| dwg_18.3mb 브라우저 로드 | 3.7 s | 4.0 s | +| wasm 메모리 (노면 / dwg_18.3mb) | 672 / 546 MB | 773 / 505 MB | + +- 크기가 커진 원인: acadrust 0.6 이 DXF/DWG 쓰기, ACIS 등을 포함해 라이브러리 자체가 커졌다. 기본 feature 는 비어 있어 끌 수 있는 것이 없다. +- `opt-level = "z"` 를 시험했다: brotli 742 KB(−9%) 대신 파싱이 36% 느려져서(3.5 → 4.7 s) 채택하지 않았다. + +## 6. 남은 것 + +- Viewer2D 가 `DIMENSION_ARC` / `DIMENSION_LARGE_RADIAL` 을 그리지 않는다. 블록 렌더 분기에 추가하면 된다. 샘플 20개에는 해당 엔티티가 없다. +- XDATA: acadrust 는 `common.extended_data` 로 읽지만 dwg-wasm 이 parseResult 에 내보내지 않는다 (업그레이드 전과 같다). +- wasm 에 컴파일되는 Rust 의존성의 라이선스 고지 생성 ([`license-mpl2-acadrust.md`](./license-mpl2-acadrust.md) §6). +- `dist2/` 재빌드와 pages.dev 재배포 전까지는 배포본이 옛 고지(0.4.1 패치)를 보여 준다. diff --git a/docs/license-mpl2-acadrust.md b/docs/license-mpl2-acadrust.md index c71dd4a..e7f1539 100644 --- a/docs/license-mpl2-acadrust.md +++ b/docs/license-mpl2-acadrust.md @@ -3,135 +3,87 @@ | 항목 | 내용 | |------|------| | 작성 목적 | 파서(acadrust, MPL-2.0)를 담은 wasm 을 공개 배포하면서 지켜야 할 의무를 확정하고 조치 내역 기록 | -| 대상 배포물 | `https://dwg-dxf-viewer-sample.pages.dev/` (Cloudflare Pages, 공개) | -| 검토일 | 2026-08-04 | -| 상태 | **조치 완료** — 고지 파일·MPL 원문·패치 동봉, 사이트에서 링크 | +| 대상 배포물 | `https://dwg-dxf-viewer-sample.pages.dev/` (Cloudflare Pages, **공개**) | +| 최초 검토 | 2026-08-04 (0.4.1 + 로컬 패치) | +| 갱신 | 2026-10-19 — **acadrust 0.6.5 무수정으로 교체**, 로컬 패치 폐기 | +| 상태 | 소스 트리 조치 완료. **배포본(dist2 / pages.dev)은 재빌드·재배포 전까지 옛 고지** | --- -## 0. 결론 (세 줄) +## 0. 결론 -1. **이번 lineweight 작업은 MPL 파일을 건드리지 않았다.** 수정한 `dwg-wasm/src/lib.rs` 는 - 우리 MIT 코드다. → MPL 의무가 *새로* 생기지 않았다. -2. 그러나 **이전부터** acadrust 를 한 파일 패치해서 wasm 에 컴파일해 공개 배포 중이었고, - 그 상태가 **MPL-2.0 §3.2 위반**이었다. 라이선스 원문도 고지도 소스 입수 경로도 없었다. -3. **upstream(hakanaktt/acadrust)에 PR 을 올릴 의무는 없다.** MPL 은 기여 강제가 아니다. - **배포물에 고지 + 소스 입수 경로만 넣으면 된다.** ← 이번에 그렇게 조치했다. - ---- +1. **acadrust 를 0.6.5 (crates.io) 무수정으로 쓴다.** 로컬 패치가 필요 없어졌으므로 + "수정본 소스 공개" 의무가 없다. 남는 의무는 MPL 원문 동봉 + 고지 + 소스 위치 안내뿐이다. +2. **우리 래퍼 `dwg-wasm` 은 MIT** (MPL 은 파일 단위라 번지지 않는다). + 0.6.5 대응으로 고친 곳(할당자, failsafe, API 변경)은 전부 이 래퍼 안이다. +3. **upstream PR 의무는 없다.** ## 1. 무엇이 MPL 이고 무엇이 우리 것인가 -| 코드 | 위치 | 라이선스 | 이번 세션에서 수정? | -|------|------|----------|---------------------| -| **acadrust 0.4.1** (DWG 파서 본체) | `hmwebviewer/rust/acadrust/` | **MPL-2.0** | **아니오** | -| dwg-wasm (wasm-bindgen 래퍼 + JSON 직렬화) | `hmwebviewer/rust/dwg-wasm/src/lib.rs` | MIT (우리 코드) | 예 (lineWeight 필드 추가) | -| Viewer2D 외 프론트엔드 | `src/` | MIT | 예 | +| 코드 | 위치 | 라이선스 | 수정 여부 | +|------|------|----------|-----------| +| **acadrust 0.6.5** (DWG 파서 본체) | crates.io, `dwg-wasm/Cargo.toml` 에서 `=0.6.5` 고정 | **MPL-2.0** | **무수정** | +| dwg-wasm (wasm-bindgen 래퍼 + JSON 직렬화) | `hmwebviewer/rust/dwg-wasm/` | MIT (우리 코드) | 수정함 | +| Viewer2D 외 프론트엔드 | `src/` | MIT | — | -MPL-2.0 은 **파일 단위(file-level) 카피레프트**다. GPL 처럼 프로젝트 전체로 번지지 않는다. -MPL 파일을 고쳤으면 **그 파일만** MPL 로 유지하고 소스를 공개하면 되고, -MPL 파일을 호출·링크하는 우리 코드(§3.3 의 "Larger Work")는 우리가 원하는 라이선스로 배포할 수 있다. +## 2. 0.4.1 시절 고지가 틀렸던 이유 (2026-10-19 확인) -→ **`lib.rs` 에 필드 세 개 추가한 것은 MPL 전염 사유가 아니다.** +2026-08-04 고지는 "한 파일만 수정"이라고 했지만, 실제 vendored 0.4.1 은 +**2파일 3건**이 원본과 달랐다 (`hmwebviewer` `feat/subdmesh-render` 브랜치 기준). -## 2. 그럼에도 의무가 있는 이유 — 이미 한 파일을 고쳤다 +| 파일 | 수정 | +|---|---| +| `object_reader/entities.rs` | `read_mesh` 배열 개수를 남은 비트로 제한 (대형 SubD 메쉬 손상 수정) | +| `object_reader/entities.rs` | OLE2FRAME 네 모서리 좌표를 데이터 헤더에서 추출 | +| `dwg_document_builder.rs` | 그 좌표를 엔티티에 대입 | -vendored acadrust 를 crates.io 원본과 diff 하면 **정확히 한 파일**이 다르다. +공개했던 `acadrust-0.4.1-read_mesh.patch` 는 원본이 아니라 OLE 중간 수정본을 기준으로 +만들어져서, 원본 0.4.1 에 `git apply` 하면 `entities.rs:2350` 에서 실패했다. +즉 배포된 wasm 의 소스를 재현할 수 없었다 → MPL §3.2(a) 미충족. -```bash -diff -rq ~/.cargo/registry/src/index.crates.io-*/acadrust-0.4.1/src \ - hmwebviewer/rust/acadrust/src -# → src/io/dwg/dwg_stream_readers/object_reader/entities.rs 만 differ -``` +## 3. 0.6.5 가 두 수정을 대체하는 근거 -`read_mesh` 의 배열 길이를 남은 비트 수로 제한하는 패치다(대형 SubD 메쉬 손상 수정, -[`subdmesh-rendering.md`](./subdmesh-rendering.md)). **이 파일은 Modified Covered -Software** 이고, 그 소스는 MPL 하에 제공되어야 한다. +같은 도면을 네이티브 프로브로 읽어 비교했다 (2026-10-19). -그리고 `.wasm` 은 acadrust 를 컴파일해 담은 **Executable Form** 이다. 공개 사이트에서 -브라우저로 내려보내는 순간 MPL 상 "Distribution" 에 해당한다. +| 샘플 | 원본 0.4.1 | 우리 패치본 | 0.6.5 무수정 | +|---|---|---|---| +| 대산당진 노면 MESH#1 | verts 100000 / faces 14 (손상) | 105497 / 185444 / 290931 | **105497 / 185444 / 290931** | +| C0060203 OLE2FRAME 좌표 | (1,1,0)/(0,0,0) 기본값 | (20584.21, 25712.29)–(39654.45, 13712.29) | **같음** | -### 적용되는 조항 +업그레이드에 따른 래퍼 변경과 회귀 결과는 [`acadrust-0.6.5-upgrade.md`](./acadrust-0.6.5-upgrade.md). -| 조항 | 요구 | -|------|------| -| §3.1 | Source Code Form 을 배포하면 MPL 하에 배포하고 라이선스 사본을 동봉 | -| **§3.2** | **Executable Form 배포 시**: (a) 해당 Covered Software 의 Source Code Form 을 MPL 하에 제공하고, (b) **수령자에게 그 입수 방법을 알릴 것** (배포 비용 이상 청구 금지) | -| §3.3 | Larger Work(우리 앱)는 다른 라이선스로 배포 가능 — 위 (a)(b)를 지키는 한 | -| §3.4 | 라이선스·저작권 고지를 제거하지 말 것 | +## 4. 적용되는 조항 (무수정 사용 기준) -**MPL 에는 upstream 기여 의무 조항이 없다.** §3.2 는 "수령자에게 제공"이지 -"원저자에게 반영"이 아니다. +| 조항 | 요구 | 조치 | +|------|------|------| +| §3.2(a)(b) | Executable Form 배포 시 소스를 MPL 로 제공하고 수령자에게 입수 방법을 알릴 것 | 고지에 crates.io 다운로드 URL·커밋·SHA-256 명시 | +| §3.1 / §3.4 | 라이선스 사본 동봉, 고지 제거 금지 | `public/licenses/acadrust-MPL-2.0.txt` (0.6.5 `LICENSE` 와 동일 확인) | +| §3.3 | Larger Work(우리 앱)는 다른 라이선스 가능 | dwg-wasm·Viewer2D 는 MIT | -## 3. 위반 상태였던 지점 (조치 전) +crates.io 는 게시된 버전을 삭제하지 않는다(yank 해도 다운로드 가능). 그래서 정확한 버전 +링크를 소스 입수 경로로 삼는다. FAQ 가 "링크만으로 충분"하다고 명시하지는 않으므로, +상용 납품처럼 더 확실해야 하는 배포에서는 `.crate` 파일(4.1MB)을 함께 두는 방안을 검토한다. -- 배포 사이트에 MPL-2.0 **원문 없음** -- acadrust 를 쓴다는 **고지 없음** (README 표에만 한 줄, 배포물에는 미포함) -- 패치된 `entities.rs` 소스를 **얻을 방법 없음** - - `hmwebviewer` GitHub 저장소는 비공개(API 404) - - 샘플 저장소는 사내 gitea - - 즉 공개 배포 대상자가 소스에 접근할 경로가 전무 - -## 4. 조치 사항 (완료) - -### 4-1. 배포물에 동봉 +## 5. 배포물 구성 | 파일 | 배포 URL | 내용 | |------|----------|------| -| `public/licenses/acadrust-MPL-2.0.txt` | `/licenses/acadrust-MPL-2.0.txt` | MPL-2.0 원문 (§3.1·§3.4) | -| `public/licenses/acadrust-0.4.1-read_mesh.patch` | `/licenses/acadrust-0.4.1-read_mesh.patch` | 우리 수정분 diff (§3.2(a)) | -| `public/licenses/THIRD-PARTY-NOTICES.md` | `/licenses/THIRD-PARTY-NOTICES.md` | 컴포넌트·버전·업스트림·수정 여부·복원 절차 (§3.2(b)) | +| `public/licenses/acadrust-MPL-2.0.txt` | `/licenses/acadrust-MPL-2.0.txt` | MPL-2.0 원문 | +| `public/licenses/THIRD-PARTY-NOTICES.md` | `/licenses/THIRD-PARTY-NOTICES.md` | 컴포넌트·버전·커밋·SHA-256·소스 입수 방법 | -저장소 루트에도 같은 내용의 [`../THIRD-PARTY-NOTICES.md`](../THIRD-PARTY-NOTICES.md) 를 둔다. - -### 4-2. 사이트에서 링크 - -`index.html` 우측 "Module recipe" 패널 하단에 고지 링크 추가. -§3.2(b) 의 "reasonable manner" 요건은 **수령자가 실제로 찾을 수 있는 위치**를 요구한다. - -### 4-3. 소스 복원 절차 명시 - -원본 크레이트 + 패치 조합이면 컴파일된 소스를 바이트 단위로 재현할 수 있다. - -```bash -curl -O https://crates.io/api/v1/crates/acadrust/0.4.1/download -tar xf download && cd acadrust-0.4.1 -patch -p1 < acadrust-0.4.1-read_mesh.patch -``` - -업스트림 커밋 `f249c2f816acf36ee51cd5533716bdd443c2517e` 도 고지에 적어 뒀다 -(크레이트의 `.cargo_vcs_info.json` 값). - -## 5. 질문에 대한 답 - -> **"해당 레포(upstream)에 올려야 하나, 배포시 문서만 추가하면 되나?"** - -**문서(고지) + 소스 입수 경로만 배포물에 넣으면 된다. upstream PR 은 의무가 아니다.** - -| 선택지 | MPL 상 필요? | 판단 | -|--------|--------------|------| -| 배포물에 MPL 원문 + 고지 + 패치 동봉 | **필수** | ✅ 이번에 조치 | -| upstream `hakanaktt/acadrust` 에 PR | 아니오 | 선택 — read_mesh 수정은 일반 버그픽스라 올리면 유지보수 부담이 준다 (권장, 의무 아님) | -| `hmwebviewer` 저장소 공개 전환 | 아니오 | 불필요 — 패치 동봉으로 §3.2 충족 | -| 패치된 acadrust 전체 소스를 이 저장소에 vendoring | 아니오 | 더 엄격한 대안. 189 파일이 샘플 저장소에 들어와 무거워짐. 원본+패치 방식은 배포판(distro) 관행과 동일하고 §3.2 를 충족 | - -> **"lineweight 작업으로 라이선스 의무가 생겼나?"** - -**아니오.** 이번에 고친 `dwg-wasm/src/lib.rs` 는 MIT 인 우리 파일이고, MPL 파일은 -건드리지 않았다(위 §2 diff 로 확인). 의무는 **이전 read_mesh 패치 + wasm 공개 배포**에서 -이미 발생해 있었고, 이번에 뒤늦게 정리한 것이다. +`index.html` "Module recipe" 패널 하단에서 두 곳으로 링크한다 (§3.2(b) "reasonable manner"). +옛 `acadrust-0.4.1-read_mesh.patch` 는 삭제했다. ## 6. 앞으로 지킬 것 (체크리스트) -- [ ] `rust/acadrust/` 아래 파일을 고치면 → 패치 파일을 다시 뽑아 `public/licenses/` 갱신 -- [ ] acadrust 버전을 올리면 → 고지의 버전·커밋·패치를 함께 갱신 +- [ ] acadrust 를 고치지 않는다. 고쳐야 하면 fork 소스 전체를 공개 위치에 두고 고지를 "modified" 로 바꾼다 +- [ ] acadrust 버전을 올리면 → 고지의 버전·커밋·SHA-256 갱신 (`Cargo.lock` checksum) - [ ] 새 서드파티를 번들하면 → `THIRD-PARTY-NOTICES.md` 에 행 추가 -- [ ] MPL 파일에서 라이선스 헤더 주석을 지우지 말 것 (§3.4) -- [ ] 배포 전 `/licenses/` 3개 파일이 실제로 서빙되는지 확인 +- [ ] 배포 전 `/licenses/` 2개 파일이 실제로 서빙되는지 확인 +- [ ] (미해결) wasm 에 컴파일되는 Rust 의존성(MIT/Apache/BSD 등)의 고지 생성 — `cargo about` 등 ## 7. 참고 - MPL-2.0 원문: [`../public/licenses/acadrust-MPL-2.0.txt`](../public/licenses/acadrust-MPL-2.0.txt) -- FAQ: https://www.mozilla.org/MPL/2.0/FAQ/ (Q: file-level copyleft, Q: 배포 의무 범위) -- 수정 경위: [`subdmesh-rendering.md`](./subdmesh-rendering.md) -- 이번 파서 변경(MIT 영역): [`lineweight-rendering.md`](./lineweight-rendering.md) §4-1 +- FAQ: https://www.mozilla.org/MPL/2.0/FAQ/ (Q6 사내 사용, Q8 실행 파일 배포, Q17 "distribute" 의미) +- MESH 수정 경위: [`subdmesh-rendering.md`](./subdmesh-rendering.md)