Compare commits

...
Author SHA1 Message Date
minsungandClaude Opus 5.5 1aa927e2e9 chore(samples): add test drawings, captures and parse dumps
- public/samples: C0060203-002 (the Korean-text repro drawing the docs
  referred to but the repo lacked), dwg_1.60mb, dwg_18.3mb.
- dist2/samples: the large-DWG, road-surface MESH, manhole and civil PDF
  samples plus the MESH / lineweight comparison screenshots.
- dist2/assets/index-B3-ohk5x.js: a build bundle left from a dist2 build.
- C0060202.json, SAN01.json, C0060202.zip: full parseResult dumps used
  while debugging (C0060202 = civil.dwg).

dist2/samples/configBak (EG-BIM registry/CUI backups) is unrelated to
this viewer and stays out of the repo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:49:07 +09:00
minsungandClaude Opus 5.5 ae77253229 docs: sample test and error-handling status report (2026-10-19)
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>
2026-10-19 19:48:44 +09:00
minsungandClaude Opus 5.5 aa27945d61 feat(viewer2d): 2.5D view, viewport fill transform and Z-aware fit box
- 2.5D view: a toolbar toggle (plus an options-panel checkbox) re-aims the
  orthographic camera at an SE-isometric angle and unlocks orbit, so the
  CAD elevation already in the vertex buffers (contours, TIN, 3D
  polylines) becomes visible. Nothing is re-tessellated; switching back
  restores the locked top view. A Z exaggeration slider (persisted in the
  options store) makes kilometre-wide sheets with metres of relief
  legible; picking and the X/Y readout intersect the Z=0 plane.
- Viewport fills: SOLID/HATCH fills and dimension arrowheads drawn
  through a paper-space VIEWPORT now get the model-to-paper transform
  (_fillXf / _bakeFillXf), as lines already did via pushSeg.
- The trimmed content box keeps the drawing's real Z range instead of
  collapsing to z=0, so the 2.5D fit and clip slab cover the relief.
- src/topProgress.ts: driver for the existing #progress loading bar. It
  is not imported from main.ts yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:48:19 +09:00
minsungandClaude Opus 5.5 e51114dbfd docs: record the acadrust 0.6.5 upgrade with a capture comparison report
- acadrust-0.6.5-upgrade.md: what changed in dwg-wasm and why (failsafe
  reads, 32 MiB wasm memory growth, API changes), the field-level parse
  diff with each cause, cost (wasm size, load time) and what is left.
- acadrust-0.6.5-upgrade-report.html: self-contained report with old/new
  captures of all 22 samples, zoomed checks of the formerly patched MESH
  and OLE2FRAME paths, and a diff image for each of the 5 changed views.
- license-mpl2-acadrust.md / README: the obligation is now license text
  plus source location; records why the 0.4.1 notice was wrong.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:44:15 +09:00
minsungandClaude Opus 5.5 129f0af25e build(dwg): ship the parser wasm built on unmodified acadrust 0.6.5
The shipped wasm was built from a vendored acadrust 0.4.1 carrying local
changes in two files (read_mesh array bounds, OLE2FRAME corner decoding),
and the published read_mesh patch did not even apply to the pristine
crate, so the notice could not reproduce the source compiled into the
wasm (MPL-2.0 3.2). acadrust 0.6.5 already does both on its own: the
road-surface MESH and the C0060203 OLE2FRAME come out identical to the
patched build, so the parser now uses the crate exactly as crates.io
serves it.

The notices name 0.6.5, its upstream commit and the crate SHA-256 (equal
to the Cargo.lock checksum the build used), the stale patch file is
removed, and the page links to the crate source instead.

Verified on 22 samples, loading each with the old and the new wasm in
Chrome: all load, 17 render pixel-identical, and the 5 that differ are
0.4.1 misreads that 0.6.5 corrects. The wrapper changes this needed live
in hmwebviewer rust/dwg-wasm (branch chore/acadrust-0.6.5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:44:07 +09:00
57 changed files with 2528745 additions and 271 deletions

No files matched your search

+1647147
View File
File diff suppressed because it is too large. Load diff
BIN
View File
Binary file not shown.
+6 -4
View File
@@ -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)
+872878
View File
File diff suppressed because it is too large. Load diff
+15 -24
View File
@@ -10,43 +10,34 @@ Served copies of the license texts live under
---
## acadrust 0.4.1 — Mozilla Public License 2.0 — **MODIFIED**
## acadrust 0.6.5 — Mozilla Public License 2.0 — unmodified
| | |
|---|---|
| Component | `acadrust` (DWG/DXF parser, Rust) |
| Version | 0.4.1 |
| Version | 0.6.5 |
| License | MPL-2.0 — full text: [`public/licenses/acadrust-MPL-2.0.txt`](./public/licenses/acadrust-MPL-2.0.txt) (`/licenses/acadrust-MPL-2.0.txt`) |
| Upstream | https://github.com/hakanaktt/acadrust · https://crates.io/crates/acadrust/0.4.1 |
| Upstream commit | `f249c2f816acf36ee51cd5533716bdd443c2517e` (from the crate's `.cargo_vcs_info.json`) |
| Upstream | https://github.com/hakanaktt/acadrust · https://crates.io/crates/acadrust/0.6.5 |
| Upstream commit | `289a616da6c68518218594aa80802cbe7fa71309` (from the crate's `.cargo_vcs_info.json`) |
| Crate SHA-256 | `5eaa72520f70eb6f7f09b06f44e1ed0d8fad5fa743364f2c3715c30df962ec7c` (the `Cargo.lock` checksum the build used) |
| Author | Hakan AK |
| Shipped as | compiled into `assets/acadrust_dwg_bg-*.wasm` (Executable Form) |
**This copy is modified.** One file differs from the published crate:
```
src/io/dwg/dwg_stream_readers/object_reader/entities.rs (read_mesh array-count bounds)
```
The modification bounds `read_mesh`'s array counts by the bits remaining in the
object stream instead of the blanket 100 000-item guard, which truncated and
thereby corrupted large SubD meshes.
**This copy is not modified.** The `.wasm` is built from the published crate
exactly as crates.io serves it.
### How to obtain the Source Code Form (MPL-2.0 §3.2)
1. Get the unmodified crate source — `cargo vendor`, or
`https://crates.io/api/v1/crates/acadrust/0.4.1/download`, or the upstream
commit above.
2. Apply [`public/licenses/acadrust-0.4.1-read_mesh.patch`](./public/licenses/acadrust-0.4.1-read_mesh.patch)
(`/licenses/acadrust-0.4.1-read_mesh.patch` on the deployed site):
Download the crate, which is the complete source compiled into the shipped
`.wasm`:
```bash
tar xf acadrust-0.4.1.crate && cd acadrust-0.4.1
patch -p1 < acadrust-0.4.1-read_mesh.patch
```
```bash
curl -L -o acadrust-0.6.5.crate https://static.crates.io/crates/acadrust/acadrust-0.6.5.crate
tar xzf acadrust-0.6.5.crate
```
The result is the exact Source Code Form of the acadrust code compiled into the
shipped `.wasm`. Both the original and the modified file remain under MPL-2.0.
or `cargo vendor` in any project that depends on `acadrust = "=0.6.5"`, or the
upstream commit above.
---
File diff suppressed because it is too large. Load diff
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.
+299
View File
@@ -0,0 +1,299 @@
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>acadrust 업그레이드 보고서</title>
<style>
:root {
--bg: #ffffff; --fg: #1d2129; --muted: #5b6270; --line: #dfe3ea;
--soft: #f4f6f9; --accent: #2457c5; --code-bg: #eef1f6; --shadow: 0 1px 2px rgba(0,0,0,.06);
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #12151b; --fg: #e3e6ec; --muted: #9aa3b2; --line: #2b313c;
--soft: #1a1f27; --accent: #7aa2ff; --code-bg: #222833; --shadow: none;
}
}
:root[data-theme="dark"] {
--bg: #12151b; --fg: #e3e6ec; --muted: #9aa3b2; --line: #2b313c;
--soft: #1a1f27; --accent: #7aa2ff; --code-bg: #222833; --shadow: none;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
margin: 0; background: var(--bg); color: var(--fg);
font: 15px/1.65 "Pretendard", "Malgun Gothic", "Apple SD Gothic Neo", system-ui, sans-serif;
}
main { max-width: 1180px; margin: 0 auto; padding: 32px 16px 80px; }
h1 { font-size: 1.75rem; margin: 0 0 .6em; letter-spacing: -.01em; }
h2 { font-size: 1.3rem; margin: 2.2em 0 .7em; padding-bottom: .3em; border-bottom: 1px solid var(--line); }
h3 { font-size: 1.08rem; margin: 1.8em 0 .6em; }
p, li { max-width: 78ch; }
a { color: var(--accent); }
hr { border: 0; border-top: 1px solid var(--line); margin: 2.4em 0; }
blockquote { margin: 0 0 1.4em; padding: .7em 1em; background: var(--soft); border-left: 3px solid var(--accent); border-radius: 4px; color: var(--muted); }
blockquote p { margin: .2em 0; }
code { font: .88em/1.4 ui-monospace, "Cascadia Mono", Consolas, monospace; background: var(--code-bg); padding: .1em .35em; border-radius: 4px; }
pre { background: var(--code-bg); padding: 12px 14px; border-radius: 6px; overflow-x: auto; }
pre code { background: none; padding: 0; }
.tbl { overflow-x: auto; margin: .8em 0 1.4em; border: 1px solid var(--line); border-radius: 6px; box-shadow: var(--shadow); }
table { border-collapse: collapse; width: 100%; font-size: .92em; }
th, td { padding: 7px 10px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
th { background: var(--soft); font-weight: 600; white-space: nowrap; }
tr:last-child td { border-bottom: 0; }
.tbl.shots table { table-layout: fixed; }
.tbl.shots th { white-space: normal; }
.tbl.shots td { text-align: center; color: var(--muted); font-size: .9em; }
img.shot { width: 100%; height: auto; display: block; border-radius: 4px; cursor: zoom-in; background: #0b0d10; }
.toolbar { position: fixed; bottom: 12px; right: 12px; z-index: 10; }
.toolbar button { font: inherit; font-size: .85em; padding: 5px 10px; border: 1px solid var(--line); background: var(--bg); color: var(--fg); border-radius: 6px; cursor: pointer; }
#lb { position: fixed; inset: 0; background: rgba(0,0,0,.88); display: none; align-items: center; justify-content: center; z-index: 20; cursor: zoom-out; padding: 16px; }
#lb.open { display: flex; }
#lb img { max-width: 100%; max-height: 100%; border-radius: 4px; }
@media (max-width: 720px) {
body { font-size: 14px; }
.tbl.shots table, .tbl.shots tbody, .tbl.shots tr, .tbl.shots td, .tbl.shots thead { display: block; width: 100%; }
.tbl.shots thead { display: none; }
.tbl.shots td { border-bottom: 1px solid var(--line); }
}
@media print { .toolbar, #lb { display: none !important; } img.shot { break-inside: avoid; } }
.badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: .82em; font-weight: 600; white-space: nowrap; }
.b-same { background: #e3f4e8; color: #17663a; }
.b-better { background: #e6eefc; color: #1f4fae; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .b-same { background: #173524; color: #8fdcae; } :root:not([data-theme="light"]) .b-better { background: #1b2a48; color: #9dbcff; } }
:root[data-theme="dark"] .b-same { background: #173524; color: #8fdcae; }
:root[data-theme="dark"] .b-better { background: #1b2a48; color: #9dbcff; }
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; margin: 1em 0 1.6em; }
.kpi { border: 1px solid var(--line); border-radius: 8px; padding: 10px 14px; background: var(--soft); }
.kpi b { display: block; font-size: 1.45em; line-height: 1.2; }
.kpi span { color: var(--muted); font-size: .88em; }
td.num, th.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cap { text-align: left !important; color: var(--fg) !important; font-size: .92em; }
.fname { font-weight: 600; }
.sub { color: var(--muted); font-size: .85em; }
</style>
</head>
<body>
<div class="toolbar"><button type="button" id="theme">테마 전환</button></div>
<main>
<h1>acadrust 0.4.1 → 0.6.5 업그레이드 보고서</h1>
<blockquote>
<p>대상: <code>dwg-dxf-viewer-sample</code> 뷰어의 DWG 파서 wasm (<code>hmwebviewer/rust/dwg-wasm</code>)<br>
비교: acadrust 0.4.1 + 로컬 패치 (현재 배포본과 같은 wasm) ↔ acadrust 0.6.5 무수정<br>
작성: 2026-10-19 · 상태: <code>수정 완료·검증됨</code> (아래 캡처와 수치는 모두 실제 실행 결과)</p>
</blockquote>
<h2>1. 핵심</h2>
<div class="kpis">
<div class="kpi"><b>22 / 22</b><span>양쪽 모두 정상 로드</span></div>
<div class="kpi"><b>17 / 22</b><span>기본 화면 픽셀 동일</span></div>
<div class="kpi"><b>5</b><span>화면이 달라진 샘플 — 전부 개선</span></div>
<div class="kpi"><b>0</b><span>콘솔 에러 (양쪽)</span></div>
</div>
<ul>
<li><strong>기존 샘플 22개(DWG 21 + DXF 1)가 0.6.5 에서도 모두 정상으로 열린다.</strong> 기본 탭(Model/Layout)과 엔티티 수가 0.4.1 과 같고, 콘솔 에러는 양쪽 모두 0이다.</li>
<li><strong>17개는 기본 화면이 픽셀 단위로 같다.</strong> 나머지 5개는 0.4.1 이 잘못 읽던 데이터를 0.6.5 가 바로잡은 결과이며, 나빠진 화면은 없다 (§5).</li>
<li><strong>0.4.1 에 로컬 패치로 고쳐 두었던 두 기능(MESH, OLE2FRAME)은 0.6.5 무수정으로 화면이 픽셀 단위로 같다</strong> (§4). 그래서 패치를 버리고 acadrust 를 고치지 않은 채로 쓸 수 있게 됐다.</li>
<li>파싱 결과: DWG 21개, 엔티티 381,811개 전부 짝이 맞는다 (누락·추가 0). 값이 바뀐 엔티티는 2,925개(0.77 %)이며 원인을 모두 확인했다 (§7).</li>
<li>대가: wasm 크기 brotli 294 KB → 815 KB, 브라우저 로드 시간 약 2~9 % 증가 (§9).</li>
</ul>
<h2>2. 비교 방법</h2>
<ul>
<li>같은 뷰어 코드(작업 트리)를 띄우고 <strong>파서 wasm 파일만</strong> 0.4.1 판 → 0.6.5 판으로 바꿔 같은 절차를 두 번 실행했다.</li>
<li>Chrome headless (실제 GPU, ANGLE D3D11), 화면 1280×800. 샘플마다 새 브라우저 컨텍스트에서 파일을 열고, 상태바에 <code>✓ 파일명</code> 이 뜨면 로드 성공으로 판정했다.</li>
<li>캡처는 UI 패널을 숨기고 도면만 찍었다. 두 캡처를 픽셀 단위로 비교해 색 차이(RGB 합 30 초과)가 난 픽셀 비율을 "화면 차이"로 적었다.</li>
<li>차이가 난 곳과 기존 패치 기능은 같은 좌표로 확대해 한 번 더 찍었다. 차이 이미지는 달라진 픽셀을 <span style="color:#d0f">자홍색</span>으로 칠한 것이다.</li>
<li>별도로 Node 에서 두 wasm 의 파싱 결과(JSON)를 엔티티 handle 단위로 비교했다 (§7).</li>
</ul>
<h2>3. 전체 결과</h2>
<div class="tbl"><table>
<thead><tr><th>#</th><th>파일</th><th>위치</th><th class="num">MB</th><th>기본 탭</th><th class="num">엔티티</th><th class="num">로드 0.4.1 → 0.6.5</th><th class="num">화면 차이</th><th>판정</th></tr></thead>
<tbody>
<tr><td>1</td><td class="fname">BasicSample.dwg</td><td class="sub">public/samples</td><td class="num">0.4</td><td>Model</td><td class="num">7,309</td><td class="num">394 → 435 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>2</td><td class="fname">C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwg</td><td class="sub">public/samples</td><td class="num">5.4</td><td>Layout</td><td class="num">17,810</td><td class="num">958 → 987 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>3</td><td class="fname">C0060203-001-표준단면도(2차로,자연환기300m이상).dwg</td><td class="sub">public/samples</td><td class="num">0.4</td><td>Model</td><td class="num">2,068</td><td class="num">347 → 412 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>4</td><td class="fname">C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg</td><td class="sub">public/samples</td><td class="num">0.8</td><td>Model</td><td class="num">5,979</td><td class="num">314 → 356 ms</td><td class="num">0.02 %</td><td><span class="badge b-better">개선</span></td></tr>
<tr><td>5</td><td class="fname">bb.dwg</td><td class="sub">public/samples</td><td class="num">0.7</td><td>Layout</td><td class="num">438</td><td class="num">231 → 307 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>6</td><td class="fname">dwg_1.60mb.dwg</td><td class="sub">public/samples</td><td class="num">1.6</td><td>Model</td><td class="num">21,330</td><td class="num">1,139 → 1,253 ms</td><td class="num">0.0089 %</td><td><span class="badge b-better">개선</span></td></tr>
<tr><td>7</td><td class="fname">dwg_18.3mb.dwg</td><td class="sub">public/samples</td><td class="num">18.4</td><td>Model</td><td class="num">82,393</td><td class="num">3,920 → 4,024 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>8</td><td class="fname">simple.dxf</td><td class="sub">public/samples</td><td class="num">0.0</td><td>—</td><td class="num">6</td><td class="num">55 → 54 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>9</td><td class="fname">04manhole1-simplify.dwg</td><td class="sub">dist2/samples</td><td class="num">0.4</td><td>Layout</td><td class="num">7,035</td><td class="num">357 → 421 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>10</td><td class="fname">대산당진 2공구_노면_20260804_143854.dwg</td><td class="sub">dist2/samples</td><td class="num">37.1</td><td>Model</td><td class="num">65,495</td><td class="num">5,651 → 5,737 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>11</td><td class="fname">test.dwg</td><td class="sub">dist2/samples</td><td class="num">18.4</td><td>Model</td><td class="num">82,393</td><td class="num">3,719 → 4,043 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>12</td><td class="fname">a. 거더배치 삽도_25.02.28.dwg</td><td class="sub">dwg2model</td><td class="num">0.2</td><td>Layout</td><td class="num">1,433</td><td class="num">453 → 484 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>13</td><td class="fname">a. 교대배치 삽도_25.02.28.dwg</td><td class="sub">dwg2model</td><td class="num">0.4</td><td>Layout</td><td class="num">2,138</td><td class="num">320 → 293 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>14</td><td class="fname">a. 교량시종점 삽도_25.02.28.dwg</td><td class="sub">dwg2model</td><td class="num">0.4</td><td>Layout</td><td class="num">4,432</td><td class="num">377 → 353 ms</td><td class="num">3.45 %</td><td><span class="badge b-better">개선</span></td></tr>
<tr><td>15</td><td class="fname">a. 교량폭원 삽도_25.02.28.dwg</td><td class="sub">dwg2model</td><td class="num">0.5</td><td>Layout</td><td class="num">2,824</td><td class="num">210 → 258 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>16</td><td class="fname">a. 교면포장 삽도_25.02.28.dwg</td><td class="sub">dwg2model</td><td class="num">0.2</td><td>Layout</td><td class="num">1,304</td><td class="num">176 → 226 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>17</td><td class="fname">a. 중앙분리대 삽도_25.02.28.dwg</td><td class="sub">dwg2model</td><td class="num">0.4</td><td>Layout</td><td class="num">2,159</td><td class="num">267 → 260 ms</td><td class="num">18.37 %</td><td><span class="badge b-better">개선</span></td></tr>
<tr><td>18</td><td class="fname">a. 횡단경사 삽도_25.02.28.dwg</td><td class="sub">dwg2model</td><td class="num">0.5</td><td>Layout</td><td class="num">5,635</td><td class="num">343 → 341 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>19</td><td class="fname">산외교- ELEVATION 산출근거도 (울산방향).dwg</td><td class="sub">dwg2model</td><td class="num">0.6</td><td>Model</td><td class="num">11,262</td><td class="num">740 → 818 ms</td><td class="num">0.0047 %</td><td><span class="badge b-better">개선</span></td></tr>
<tr><td>20</td><td class="fname">산외교-받침배치도 (울산방향) .dwg</td><td class="sub">dwg2model</td><td class="num">0.4</td><td>Model</td><td class="num">6,240</td><td class="num">590 → 689 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>21</td><td class="fname">산외교_파이형_교각일반도(울산P11-꺾임).dwg</td><td class="sub">dwg2model</td><td class="num">1.0</td><td>Model</td><td class="num">25,927</td><td class="num">707 → 731 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
<tr><td>22</td><td class="fname">산외교_파이형_교각일반도(울산P9).dwg</td><td class="sub">dwg2model</td><td class="num">1.0</td><td>Model</td><td class="num">26,207</td><td class="num">732 → 710 ms</td><td class="num">0 %</td><td><span class="badge b-same">동일</span></td></tr>
</tbody></table></div>
<p class="sub">로드 시간은 파일 선택부터 상태바 ✓ 표시까지(파싱 + 렌더). <code>simple.dxf</code> 는 wasm 이 아니라 dxf-parser 로 읽으므로 대조군이다. <code>dwg_18.3mb.dwg</code> 와 <code>test.dwg</code> 는 바이트는 다르지만 같은 도면이다.</p>
<h2>4. 0.4.1 로컬 패치 기능 — 0.6.5 무수정으로 동일</h2>
<p>0.4.1 에서는 아래 두 가지를 acadrust 소스를 고쳐서 해결했다. 0.6.5 는 고치지 않은 상태로 같은 화면을 낸다.</p>
<h3>MESH(SubDMesh) — 노면·부체도로면 삼각망</h3>
<p class="sub">대산당진 2공구_노면_20260804_143854.dwg · 확대 화면 차이 <strong>0 %</strong></p>
<div class="tbl shots"><table><thead><tr><th>0.4.1 + 로컬 패치</th><th>0.6.5 무수정</th></tr></thead>
<tbody><tr><td><img class="shot" loading="lazy" alt="MESH(SubDMesh) — 노면·부체도로면 삼각망 0.4.1" src="data:image/jpeg;base64,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 truncated
<p>0.4.1 원본은 10만 개 상한에서 배열이 잘려 메쉬가 깨졌다 (verts 100000 / faces 14). 패치본과 0.6.5 모두 verts 105,497 / faces 185,444 / edges 290,931.</p>
<h3>OLE2FRAME — 삽입 이미지와 위치</h3>
<p class="sub">C0060203-001-표준단면도(2차로,자연환기300m이상).dwg · 확대 화면 차이 <strong>0 %</strong></p>
<div class="tbl shots"><table><thead><tr><th>0.4.1 + 로컬 패치</th><th>0.6.5 무수정</th></tr></thead>
<tbody><tr><td><img class="shot" loading="lazy" alt="OLE2FRAME — 삽입 이미지와 위치 0.4.1" src="data:image/jpeg;base64,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 truncated
<p>0.4.1 원본은 프레임 좌표를 읽지 못했다 ((1,1,0)–(0,0,0)). 패치본과 0.6.5 모두 (20584.21, 25712.29)–(39654.45, 13712.29), 추출 이미지 바이트도 동일.</p>
<h2>5. 화면이 달라진 5개 — 원인과 판정</h2>
<p>모두 0.4.1 이 잘못 읽던 값을 0.6.5 가 바로잡은 경우다. 차이 이미지에서 자홍색이 달라진 픽셀이다.</p>
<h3>a. 중앙분리대 삽도_25.02.28.dwg</h3>
<p><span class="badge b-better">개선</span> 레이아웃 전체 뷰포트를 모델 창으로 오판하던 것이 해소 — 도면을 가로지르던 검은 세로 띠가 사라지고 Fit 이 도면을 채움 · 기본 화면 차이 18.37 %</p>
<div class="tbl shots"><table><thead><tr><th>0.4.1</th><th>0.6.5</th><th>차이</th></tr></thead><tbody>
<tr><td><img class="shot" loading="lazy" alt="a. 중앙분리대 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
</tbody></table></div>
<h3>a. 교량시종점 삽도_25.02.28.dwg</h3>
<p><span class="badge b-better">개선</span> 트루컬러 해치(RGB 128,93,59)의 근사 색이 ACI 35 → 37 로 바뀌어 원본에 더 가까워짐 · 기본 화면 차이 3.45 % · 확대 화면 차이 7.80 %</p>
<div class="tbl shots"><table><thead><tr><th>0.4.1</th><th>0.6.5</th><th>차이</th></tr></thead><tbody>
<tr><td><img class="shot" loading="lazy" alt="a. 교량시종점 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td><img class="shot" loading="lazy" alt="a. 교량시종점 삽도_25.02.28.dwg 확대 0.4.1" src="data:image/jpeg;base64,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 truncated
</tbody></table></div>
<h3>C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg</h3>
<p><span class="badge b-better">개선</span> ATTDEF 정렬을 새로 읽어 동그라미 번호(①)가 원의 오른쪽 아래에서 중앙으로 옮겨짐 · 기본 화면 차이 0.02 % · 확대 화면 차이 0.02 %</p>
<div class="tbl shots"><table><thead><tr><th>0.4.1</th><th>0.6.5</th><th>차이</th></tr></thead><tbody>
<tr><td><img class="shot" loading="lazy" alt="C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 0.4.1" src="data:image/jpeg;base64,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sDNCiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLVfBZ+MKxftA+4rKrVfBZ+MKxftA+4q2j9o3pCw+U/udb2Xe4p8Kf4wr7+0H7gsqtV8Kf4wr7+0H7gsqlb7R3SU8mfc6Pst9wRERVLciIiIiIiIiIiIpdBGyRtUXtB0Quc30HI3URTbZ8Wt/Z3feFCUGnnOWqs0CjTI3+9ERFNZURERERERFNs39/f/Cl/q3KEptm/v7/AOFL/VuUJVj7Q9A+K1v+6s9p3uYiIisWRERERERERERERERERERERF9BLTkEg94XxERejI9wwXuI7iUa97RhrnAegryi7JXZK+ucXHLiSfSV66WT8931rwiSUkopYude0ACtqgBsAJXe1REXWvc3zTCkyo9nmmF9c4vcXOJc4nJJOSSvrXua1zWuIa7ZwB5/OvKLkqMnNERFxcRERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERar4LPxhWL9oH3FZVar4LPxhWL9oH3FW0ftG9IWHyn9zrey73FPhT/ABhX39oP3BZVar4U/wAYV9/aD9wWVSt9o7pKeTPudH2W+4IiIqluREREREREREREXeln6ATjTq6SMx8+WSN/4Lgu9LK6IT6GatcZYfQMjdcFEDEq6o6WMEzE6sse9ERFJUoiIiIisr5TUlNJSeAymRktOyV+XAlj3Ddu3d6fnVaoseHtDghunzTI24/EA9y70cPhE/R69HVc7OO5pOPpxhcFfcE08VVfhFURskj8GqZNLgD1mQPe3+LQqFSuu845Lpq0iNE3zxieg4D3FERWM9NSx2OkqWyl1XNLI10YcMMa3Tgkc8nVt8xUXPDSAda5LciY2Z47sPjgq5EQDJwOakiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi0lvoPCuCa6eCmElVHXwxBzWLine truncated
<tr><td><img class="shot" loading="lazy" alt="C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 확대 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAMgBQADASIAAhEBAxEB/8QAHAABAQEAAwEBAQAAAAAAAAAAAAYFAwQHAgEI/8QAaxAAAQMDAQMGBwkJCgkICAQHAAECAwQFEQYSITEHExZBldIVIlFVVmHRFBcyVHGBk6SzIzdTZXSRlKHTMzQ2QlJicoOxsiQ1V3N1doKjwSdGZmeEtMLiCCVDkqKmw+EmlrXwREdjZIbE8f/EABsBAQADAQEBAQAAAAAAAAAAAAADBAUCAQYH/8QASBEAAgECAgQLBQYFAgUFAQEBAAECAxEEIQUSMUETFBVRUlNhcZGS0iKBobHRMnKiwdPwBjM0QrJU4RYjYoLCByQ1Q/FjJeL/2gAMAwEAAhEDEQA/AP5EAB0cgAAGlS1sFRTNorntbDExDO1Mvh9S/wApvq6uo5qKru+lrq2rt9VzUjmKjJWYfHNGvFFRco5q+RTHO9b7hzMS0lVH7oo3LlY1Xexf5TF6l/tKtSirNJXi9q3P982xmnwtDSFLi+N5rKTV8uaa3x5nm0ss1ZKttl1v2s+c0vZrfYbUlW3nKlKaFtPz6M3ptKqqq4Xfst9e7GToLpWy0rlS6a4s8Sou9tJFNUu+Tc1E/WYlRTz2+aK4W+okdCj0dBUxqrXMcm9EXG9rk/8A+Gtfr3bNRWqSruNKyk1BCrcT00SJHXIqptLIifBkTKu2k3LvRU4FDgZ05ri71ab26qWsnsu7p33LZdW5tny+L0XitHYhUafsU3t1Um7vZK71lKLVrNbEt6zXbmvenrDZ6636WSuq6yvgWmqrhVsSNEhX4TI40VcbWEyrlz5CNANGhho0b2bbe1va/wB8yyLmGwkMOnZtt5tvNv8AfMrLsAALBZAAAAAAAAAAAAAAABoX7980/wCRwfZtM80L9++af8jg+zaQy/mx7n+RoUf6Kr96H/kZ4AJjPAAAAAAAAAAAAAAAB6HM6blE0zSU9ExUvtjp1YtHHlGVVOmE242/Ba9u7LURNrO7giJ54dq03CstVyguNvqH09VA/bjkbxRf+KdSp1oU8XhnVSnTdpxzi93c+x7H4rNFHHYSVdRqU3apDOLey+xp9jWT8VmkX0lptcOk26Jq9T0NHeUrvdszZkctPG/Y2EhWVuUa5E3uXGMrjO4kNSaXvmn+bfc6FzIJV+5VDFR8MnWmy9uUXdvxxNTWvge72+DVdvqKemrauVWXG2o/xo5t6rIxF37DuPqVcZXqmYfddVzVDE6aVNpVjhRVVEVeKonVw3/IU8BCrGPCOe1vWTWx77NWy79bLYynoihiZWlGTbk3rRcc9bY1G1sr7L611sZzz3S41VqpbRLO6alppHOp41aiqxXYyjVxnC44Zxk7LYYLQnOVaRz12PEp/hNiXyv6lX+b+c/HyQ2d3N0qsmr0+HPxbEvkZ5V/nfm8plOVXOVzlVVVcqq9ZdjBTVoq0fC9/wAn4v5/Xwp0dFXUUnVv/wBsHvfNKd+9Ltf2eSqqJ6qd09RK6WVy5VzlypxAFpJJWRmznKpJzm7t7WwAD04AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6VyFI2aqutNhvObdunaquxjYr4M7uvc481PROQNzl1VcadqKqz2x6bm5wjJYpF+z4nM1enNc8ZLxTMT+I1fRtV81n4ST/ACIa9RpFeK2JqqrWVEjUzx3OU6ho6oj5nU10iztbFZM3OOOHqZxxRd6cX2I1sPLWpRfYgACUlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPunmlp5mzQvVkjeDk6j4APLK9zpzk4qN8v39EAAenIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANXUNiqbJFan1MsUnhKgZXRpHnxGPc9qIuU4+J+syi15VP3roz/Vmm+1mKdetKFelBbJXv7lc6SumyKABcOQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaMVqkbG2e4StoYXJlvOJl70/ms4r8q4T1nE6kYfaZZw+ErYltUo3ttexLtbeSXa2jPaiucjWoqqq4RE6zRgtaRtbLc50o4lTKNxtSO4cG/IvFT6S5QUSK2006xuVMLUTYdIvyJ8FvzZX1mY975HK97nOcvFVXKkd6lT/pXx+i+Jctg8Lt/5s+bNQXvylL3aq5m0bNFeqeil5qmoGpRv8Wdr3bT5m4xvXgnlwiIdarooZYH1ttVz4G75YnfDh+Xyt9afPgzjmoqqejqG1FPIrJG9adfqXyp6jngNR61Pb8+/6/lkScqvERVDFq8Fe1kk4X6NrK29x2PN5SescINZ1NBdY1loI2w1bUzJSpwf/Oj7v5jJVFRcKmFQlp1FPLY1uKWKwc8PaV9aMtklsf0a3p5oAAkKYAAAAAAAAAAAAAAANC/fvmn/ACOD7Npnmhfv3zT/AJHB9m0hl/Nj3P8AI0KP9FV+9D/yM8AExngAAAAAAAAAAAAAAAA7ttoFqEWeofzFHH+6TKn/AMLfK5fIcTmoK7J8Ph6mIqKnTV3+829iS3t5I47fRTVsqsi2WtYm1JI9cMYnlVTtVVZBS060Vse7Zd+7VGNl0vqTrRvq6+s71wrrROjrZBz1LSMd4ksSIqSKn8Z7cIq9e/PzHQdZql8azULo66JqZc6Bcq35WrhyfmKiqKbTq+ytyf5vZfs3H0FTByw0ZU8A1VlmpSi7vtUY/aUeedvaWxpNp5oCoqLhUwqAvHzIAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXnIKjpuUinoWo5fdlFWQLsuxxppF/tRCDLPkRerOVWwYT4VQrF3qm5zHIvD1KdQV5JGVp2OtozEJdCX+LMTXEfM61vsWdrYuNQ3OOOJHGOb3KLGsev9QNcqZW5VDt3rkcv/EwSpg3fD032L5FvAS1sLTf/AEr5AAFktAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGlphrX3yna9qOau1lFTKL4qmaael1Rt9p1cqInjb1/oqZhBH+dLuXzZp1bcnUufXqf40wACczAAAAAAAAAAdm2SUUdax9xpp6mmTO3HDMkT3blxhytdjfjqOsU2kamzOibb6jRU1/uD3ucx0NbKx6txnCMYi5xhVyV8TU4Om3qt9zSffdtfMrYuq6dJy1XLuaTtz3bjbxucfu7Rfo7ee12fsDtXq12GXQsOo7TT11HKtzdROgqKpsyOakSP20VGNxvVELO16fs9VYrvXz8lN1p6iibEsFM6qqtqp237LkblqL4qb9yKZF4u9ot9qpLdduS2soqRksksDaivqItp7kaj1RVairua35PnMGGNVSqlQhO8Xn7cXuvazqO+1f/AKj5qnpBVayjhoTvGWa14O61b2SdVp7V3Z70R+m7fYq5J1vOoVtCs2eaT3E+fnM5z8FUxjCfLk2LxpKzQaSqNQ2rVCXGGCoZT7D7e+Dbe7fstVy71RvjKnk+Yz9MaYlu1PJc62rhtdlgk2J66dcojsZ2GN4yPx/FT58FLcKiwavs1NYLDM6yvtav9w01dM1I65HYy9z9yNmVU4KuzvREVC3isROOITp1Jaqa1souMVzP2b3e/PJO7srF3G4qcMSnSqy1U1r2UXGK5m9XWu9+fsp6zsrE2+zUacm8eoEWX3Y67uo1Ta8Tm0hR/DHHK8cnUtEOm30quu1fdaeo21w2mo45WbOEwuXSNXPHdg3ZUxyJQp/0jf8A93adSxUGnLfb4b1qCujr3PRXQWikf90kVFVPuz+ETdybky5UXdgkjXlwc9Zu+u0rZvu5vHJb2iWGJlwVRylK+vJLVV32JXTXvdkt7R+aq09a7Zp+13ehuNbL4RdIsUFVStifzbN3OeK92EVdyZ4716jh1vZqOzLZPciyr7us9PWy7bs/dH7W1jduTdwNTUN9sWr6N9ddNuzXqlp9iFtNG6SkqGNRdiNrFVVhXeibst3Ku5VO9yk3irpbZpy2xR0SwLine truncated
</tbody></table></div>
<h3>dwg_1.60mb.dwg</h3>
<p><span class="badge b-better">개선</span> 3D 폴리선 vertex 순서 수정 — 곡선을 가로지르던 가짜 직선(청록)이 사라짐 · 기본 화면 차이 0.0089 % · 확대 화면 차이 0.48 %</p>
<div class="tbl shots"><table><thead><tr><th>0.4.1</th><th>0.6.5</th><th>차이</th></tr></thead><tbody>
<tr><td><img class="shot" loading="lazy" alt="dwg_1.60mb.dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHQABAAMBAQEBAQEAAAAAAAAAAAUGBwQDCAIBCf/EAFIQAAEEAgIBAgUCBAIECQkDDQEAAgMEBREGEiETMQcUIkFRMmEVI0JxUoEWJDORFzZDYnSVobGyJTdUVXKDs9PUCDRTY4LB0USS8CY1ZHPhwv/EABoBAQEAAwEBAAAAAAAAAAAAAAABAgMEBQb/xAA6EQEAAgEDAwIDBQgBAwQDAAAAAQIRAyExBBJBUWETInEFFDJCgVJikaGxwdHwI3Lh8TNjgqKSstL/2gAMAwEAAhEDEQA/APmNERVBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERARF9L5am/E0sXSficPLXpwVmONpsX82IN/nk9xtmtD6ySPqIPnyA+aEX0llMBw9vMKfGsjxqESS1PmBdi3Ezq3sXF/Qt1+j+wJHvtRcfwnxF2pHNPjrON7UxLK+PItdHFNsfQQWOOi09u3sB+PdBgKLV+Y/DvjWErC1ByO26tqNxeyq2wGiRrjG4lrm/S7qdOAI8fuFU4OK0L84hxPJ8bYmc7TI5oZ4XEefPlhH237oKoiuP/Bzn5pOmObQyJ0SPlL0TyQNeepcHfcfbx91wWOEcors7yYDJFmt9o67njWt720Hx+6CuovWxXmrSuisxSQytOiyRpaR9vYryQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQd+AqfP53HVNb+Ysxxa1vfZwH/AOlfS+ZwlaxTsSulsNrXvmmGUTxPYfXdGXa9QsI0ItADz9R8/c4B8M2xnnWIkn/2deQ2nePYRNMn/wDz7rYMdmMtyDhmDuYs26nr5hvzrvnn9WRNLi8l5IIaQRtu9fT4GyUFr5NNlMtUh/g2Sv4d0oa+WL5J1gva4tB/mx9wwdQddCNnZ3ryoDleEbk73Kic1X65iOvDWhbI10sHQNLtxvc0fUY/sd/fRXtnaFqxjs9Xy/K3Y4MyL74fXmM0laqNsYwtDg5vYnegCABr39p6xSuZbMvs17+bjArjUcUsYpP9hrZae7iCT4AHggkKKp+UxF/Gsz2UowHIRtxdenWrS0HyOLozG0P6lhY4eXO8E/8AYdcmYlpcam5E75CPEx1q1erHeoVvRnMs7ezyDsA66nw3Wh7aICtuW4xi7Oa+cZQyInvtLH2aT3VWVgxvmTYcASSANnYcNaOgSejAsp2+POjwGQbyGKq18Unr3XukleP0+SS1v9Q/TojWiAiKngoLloQsfbu35atK3MybJ2GNnc6WNkcZ9IvL2x6BP1a8u+/u6I5jyrHYV9KcYitcksOnj9WGxJXl9OJ3oNPdhBIPpn3+w/zV5oS2r1J+VNK7grVa4x1urPXjb8zEwb0JGxguH39zrqR7LH+T8jZhp6mEmw2IyUFSnCHPtxOdIHyMbLJp7Xggd3u0PYb0gkX/ABNpW7YsSnkFJrWta2qy1Fbr6aOuiyRgJ2ANnez5+52rDPFXghkky9DFZAOE83ezjYoZGMZTE3VwjHhwkka0/UfY/fyqgzFcZqDD8otzNp15oXWzhurpHSSMkc0NYT/ybnN39R8Aa2dhWTjtS9yDjTgZ425K7jb1p75gS0+vZjaXfQC79MThrR149lRQMfm+MWbsQzXF4YKziBJLj7MzXt/cNe9wP9vH91f73wtwDq8UldnIoXznUYMYLW/4Q4SsjIcSCOuz7jyqRU4wMHdxeYsXqWVxkORihnGNc6SRjt9g0texvv1P/cr1hvh7JBzunmbuarTltz5kxSRlkkzxt4aweWk/SfAO9DekFS5TwDEYC3DVtcrir2pWCQQ2qMrSwE6+os7j/P28FcR+GuWlnggx1/DZCzPC2eOCC61sjmOb2a4MkDT5Hn2X6+NE/wA18SsqyMuk9NzIh/fqCQBofckf/pPurxw6r818c7zIuzWY6s2AbJ+n02RxEb7Dzrt9/wAnRQZrd4DyqmC6bBXnNA2TDH6oHnR8s3+FXrVSxTkMduvNBIDotlYWn/cVqPKLOQyPxeoMomVstZlV8rmDfpgNbLI92z/SXuPn2U9irPLaue5lksjJko8NVgu2a7LG3QOeT2iDQ8Ea8gjXjx/cEMKRXetmc/lJGsm4zRy0kjezf/JAD3NPnYMIafsfO/yrli+AS5MsdluCtxVdx3JZhyjmdB28n03eo72340B49wgxZFq3KOAcVxfIq2HHIL9CzYJ6PuVmyRa2Q0l7S3QLgW717g70F+Mh8EeRwsL6FnHX2j2Ecpa77f4hr2IPv/8A7DLEVizHCeTYcu+fwl1jGgkyMj9Rg1/zm7H/AGquoCIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiILp8KrUONzeQytmu2zDj8dNM+BxAbKD1j6kkHwfU/B/st3wtbJ5oYDK4yePCYFlbvNjvRGnE7PTwGgsA+/7n8nWbf/AGdqj3Ws3dZ6zfRbC0uiaXEt7F7m6BHv6YH399a8rTeR3a+Wx0tNmau4YSNc2R1nFPb2aQQQXSsA/T9OwfsfKgjsm7A8Ldd5A+layly9APnX1WmSF7tAkkb6NDnAu2d6AOvfzTviR8S8nYo42tVjfi616AWTdrdnyFpcSGRucGa1pnYj7714Hmy8A4di8JjMzSo8jxOUkvdR6vRjvQLGvDX9O7gSHuHjY9vdS2M4zzDFWK8cWUwN6g149RkuObXcGdtu6iMa3rf+f+9FUTFXMnxfAccfbpfxTK3Hd6VU2JHmYS9XPe8EDRa0RsA8gbcfyp+GrUw3zT+M1K3G+V5atqCldk2Q5khDgwEFn1HXXZ0dbA0Cqvls9znH5C/KOPWZpTLMyjkJaDnzQMcdaDtH+kDX/wCkeFRq/M+QY0hlkxzWIyXQyXazZJa7iSezHOGwdl37b+yqN5yNi0aGdZnb/pR13GJ5017Y+1FnfXjfh8znfY60BsHQxvlnH5M5yXJ3qmc4/KJZz6Uf8RY0lngN130PbQ1vfj7q9sbm878I68LWPvZF2Lld6rn/AMwxmywgeTs/REf7+B5WCIL1zHCXLOWxGIpQB9yjh4RNAJGgsd5e4eTokl+wATvsNe+lpvEaUOOLine truncated
<tr><td><img class="shot" loading="lazy" alt="dwg_1.60mb.dwg 확대 0.4.1" src="data:image/jpeg;base64,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 truncated
</tbody></table></div>
<h3>산외교- ELEVATION 산출근거도 (울산방향).dwg</h3>
<p><span class="badge b-better">개선</span> 작은 표고 텍스트 2곳의 위치 (ATTDEF 정렬) · 기본 화면 차이 0.0047 %</p>
<div class="tbl shots"><table><thead><tr><th>0.4.1</th><th>0.6.5</th><th>차이</th></tr></thead><tbody>
<tr><td><img class="shot" loading="lazy" alt="산외교- ELEVATION 산출근거도 (울산방향).dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
</tbody></table></div>
<h2>6. 전체 샘플 화면 비교 (기본 화면)</h2>
<p>파일을 열었을 때 처음 보이는 화면이다. 이미지를 누르면 크게 볼 수 있다.</p>
<div class="tbl shots"><table>
<thead><tr><th style="width:22%">파일</th><th>0.4.1</th><th>0.6.5</th></tr></thead>
<tbody>
<tr><td class="cap"><span class="fname">1. BasicSample.dwg</span><br><span class="sub">Model · 7,309 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="BasicSample.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">2. C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwg</span><br><span class="sub">Layout · 17,810 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="C0060202-001-평면및종단면도(1)(대산방향STA.18+492.08-19+411.50).dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">3. C0060203-001-표준단면도(2차로,자연환기300m이상).dwg</span><br><span class="sub">Model · 2,068 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="C0060203-001-표준단면도(2차로,자연환기300m이상).dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">4. C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg</span><br><span class="sub">Model · 5,979 엔티티</span><br><span class="badge b-better">개선 · 0.02 %</span><br><span class="sub">§5 참고</span></td><td><img class="shot" loading="lazy" alt="C0060203-002-굴착및시공순서도(2차로,자연환기300m이상).dwg 0.4.1" src="data:image/jpeg;base64,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sDNCiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLVfBZ+MKxftA+4rKrVfBZ+MKxftA+4q2j9o3pCw+U/udb2Xe4p8Kf4wr7+0H7gsqtV8Kf4wr7+0H7gsqlb7R3SU8mfc6Pst9wRERVLciIiIiIiIiIiIpdBGyRtUXtB0Quc30HI3URTbZ8Wt/Z3feFCUGnnOWqs0CjTI3+9ERFNZURERERERFNs39/f/Cl/q3KEptm/v7/AOFL/VuUJVj7Q9A+K1v+6s9p3uYiIisWRERERERERERERERERERERF9BLTkEg94XxERejI9wwXuI7iUa97RhrnAegryi7JXZK+ucXHLiSfSV66WT8931rwiSUkopYude0ACtqgBsAJXe1REXWvc3zTCkyo9nmmF9c4vcXOJc4nJJOSSvrXua1zWuIa7ZwB5/OvKLkqMnNERFxcRERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERar4LPxhWL9oH3FZVar4LPxhWL9oH3FW0ftG9IWHyn9zrey73FPhT/ABhX39oP3BZVar4U/wAYV9/aD9wWVSt9o7pKeTPudH2W+4IiIqluREREREREREREXeln6ATjTq6SMx8+WSN/4Lgu9LK6IT6GatcZYfQMjdcFEDEq6o6WMEzE6sse9ERFJUoiLine truncated
<tr><td class="cap"><span class="fname">5. bb.dwg</span><br><span class="sub">Layout · 438 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="bb.dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHQABAAIDAQEBAQAAAAAAAAAAAAUGAwQHAgEICf/EAF8QAAEDAgEGBwkNBAYIBAQHAQABAgMEEQUGEhMhMdMUFRZBVFbRIlFTVXORk5SVBzIzNTZhcXKBkrHC0ggjdLIkNEJSYqEXGDdDdbO0wSWjtfAmZIKiREVjg4Sl4fH/xAAaAQEAAwEBAQAAAAAAAAAAAAAAAwQFAgEG/8QARhEAAQICBAoGBwYGAwEBAQEAAAECAxEEFJHREhMhMUFRUlNhkgVxobHB0hYyM3KB4fAiNXOiwuIjNEJUYoIGsvEVJENj/9oADAMBAAIRAxEAPwD9UgAAAAAAAAFZwn5Z4r5NPylmKzhPyzxXyaflLNH9WJ1eKGJ0v7aififpcWYAFY2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVupVaP3QKOWVXLBiNA+mjc53csmifpEY1P7z2Pkd9EHzFkPMkbJM3SMa/NcjkzkvZU2KnzgHLMbwrKDBvcXxnBa5mF8Ew/AJqRs0EskklQ1lM9qLmq1qRqtmrtfzp85ilw+hwzJbL2SZlVUYZhOIy10lC6pVUrGx0cL9FLI9HOViqiKqX12st23avWgiIl7ImvaAcxxKryMxBeC4JlXgKSVuK0da+k4zifG6RlQyR6xsRVs+S2tE1OdrtdzlX77pVHhlPjtCslQ3CJsSp3RSYnUYpVUtK1sKpmRLHFLG2R7tK9WormrZr1uubY6afHta9qte1HNXaipdFAOfe5nJTzY3i6Uk1DWR0tDQ0LKzDHq6keyNZ1bG1FVyskZn903Pf3Lo1ul1Qq9JXRYRXU0MNfh7sMyWlfT01JjWMw0U0Ga10DXKxtOqq3RuckavkTOa5HKiqqOO0ta1jUaxEa1NiIlkPjo2Oe1zmNVzdiqmtACpZBQPwnIfI+lwuhnmpn0lPHUPqVSCWBiU99I+NVd3SuaxqsRdSvvdURSMgWFmXVI7JSmxem09XKuMxSUU8FG9mjfeZNKxGaRZUj7qJbvRyq7ORLp0IAFVpGS0WWuVOIz01StJwCjVj2QufpFZwhXNYiJdzkumpLrrTvlNfk5ljFkwzFZJsNficNWuUDqKOik4U6fW5aZJtMrVXRqtMjsz3ltR1wAGnR4lTVlTNTwrKk8MccsjJIXszWvRVb75E19yt0TWltdiHytpp58XyRfBDJIyDFlklcxqqkbOCVLc51tiXc1Lrzqic5ZAAcwy1oKWtymxLlNS43wR1IyCgfhNFLO2Vi3WRJliY7PXP8A91MixK3NXNcqvtnx3JHEcp8jcClxR1fBjzeLXVdPTYhJTwsVk8T5lzGPRmc1EeqKl1RUTNXUh0gAFMxbJ7FYKjBW4Loa6hoHSTOhxXEJ3OdOttG9ZFbI56NRZLNXUiq1drW2r2D0NRT5HUVRlGzEsIxOlxStfSzYPSy1kzGySyquczQP7hyOd75ioqZioqOtbqgAOW4XVYpkpk7jWL8CxjEK3G8Ua+lSopHzTMZoI4kmqI4GXY39y5+a1qKiKxio110SzZI1WF4Zk4srH4k7OqkSpqa3Dp6eapqZXtRXqx7GusrntRLJmtRERLI3VbAAcuyh4ZRUmX2CtwvEqisx1734a+Ckkkhl0tJFCiPlaisizXsdfPVtm2VL3NfKjC6ebGsXZlHTY6q8HhpsMfhdBJPHNC1jXfvcxjmSO0yypo6i8aNsqNTOeq9ZABU25OVON0GGV+OVuKYdjzaOFsrcOr3xwwTomc9Wxoqxv7pyp3aPRUa3vHnLfCpo/coyjwuiWtxCpdhFVFGsjnTTzyOif9quVV1IiW12RESyFuABVcuYKNrsPxCWqxqhrqdZI4KrCaF9XIjXomexzEilTNdmMXum7WtsqKQuSeSMtTgGJyYtUY3DNiWIyYg1HVz6epto2RN0qwq1LubGj8yyNZnI2yZp0QAHM8LyHxTDvc2w3B6GaR1dJTUkGJQV+JTviVjGWliiXu0jRy3auY33qqiWXNVJTIKDHocpMqnYxh1FSUs1XE+N1PLI9HKlLA1MzOjaiss1UVeZyKltVy8AAreQlNPS4fibamGSFz8WrpWo9qtVzHVD1a5L8yoqKijJSnnp8byyknhljjnxZksTnMVEkYlDStzm99M5rkunO1U5iyAAqGP1uTtZDhWK1tLitUlRSSJSTUVDWSPbDLo3OvoWKrFXNjVM6zrt1bFIDC0xTBKnJnGccpsVqIIqOvopM2F9XUwMlnikptK2NHPcqRQox7kzlzrKqrdXHTgAczSjqqnBY0mp5aatx7KSDEIqeVitdFDDPHKivTaxVhpUcqOsqPejVsq2OmHh0MTp2TujYszGuY2RWpnNa5UVyIu1EVWtunPZO8ewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAy4+IX+UaTkHwMf1U/Ag8uPiF/lGk5B8DH9VPwLD/YN618DGo/3rH9yH3vPYAK5sgAAAAAAAAAAAArOE/LPFfJp+UsxWcJ+WeK+TT8pZo/qxOrxQxOl/bUT8T9LizAArG2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGXHxC/yjScg+Bj+qn4EHlx8Qv8o0nIPgY/qp+BYf7BvWvgY1H+9Y/uQ+957ABXNkAAAAAAAAAAAAFZwn5Z4r5NPylmKzhPyzxXyaflLNH9WJ1eKGJ0v7aififpcWYAFY2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAy4+IX+UaTkHwMf1U/Ag8uPiF/lGk5B8DH9VPwLD/YN618DGo/3rH9yH3vPYAK5sgAAAAAAAAAAAArOE/LPFfJp+UsxWcJ+WeK+TT8pZo/qxOrxQxOl/bUT8T9LizAArG2AAAAAAAAAAAAAAAAAAAAAAAAAfi33TMWr25e421tXMjW1LkREcuwpT8exhKySPhM+jRzUa5XuTUubf8As2XavObf/wAeTWuV+fh8zvBP6Dg/n1U47irKhscddJrc1Vu9VVGrq2fSm0yS45ibZs1KqqRiJ7/OW2d3vNz7PtPf/jJl+3m4fMYJ/QEH8+arGsVZUorMQqEZm62q6+vv7P8AubvG2IdMn++p63oTCVUw83D5jBP3yCp+5TUTVXufYNNUyvlldG673rdVs9yJdfoQthixGYt6s1LI5VJAAHB4AAAAUb3ba2poPczxmainkgmVjWZ8a2ciOciLZebUqn4wra2rip86GZ+kVzGpnOW2tyJr85pUTo6swnRVdJE4TOkbNJn9CAfzvbitU98StfKkd7SXzrpdytRL3tqVNZ8TE61rbrLI67nsRLqmtHK1t15k1W+0sf8AyW7zs+Z7gn9EQfzyjxCsfBRSaSZVe1HSZqrayt7VT7EU1YMTrnOpnOrJVR8Uavaq87lTWlk1bHc/2Hi9EtSX28/D5nmCf0XB+K/clxCLine truncated
<tr><td class="cap"><span class="fname">6. dwg_1.60mb.dwg</span><br><span class="sub">Model · 21,330 엔티티</span><br><span class="badge b-better">개선 · 0.0089 %</span><br><span class="sub">§5 참고</span></td><td><img class="shot" loading="lazy" alt="dwg_1.60mb.dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHQABAAMBAQEBAQEAAAAAAAAAAAUGBwQDCAIBCf/EAFIQAAEEAgIBAgUCBAIECQkDDQEAAgMEBREGEiETMQcUIkFRMmEVI0JxUoEWJDORFzZDYnSVobGyJTdUVXKDs9PUCDRTY4LB0USS8CY1ZHPhwv/EABoBAQEAAwEBAAAAAAAAAAAAAAABAgMEBQb/xAA6EQEAAgEDAwIDBQgBAwQDAAAAAQIRAyExBBJBUWETInEFFDJCgVJikaGxwdHwI3Lh8TNjgqKSstL/2gAMAwEAAhEDEQA/APmNERVBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERARF9L5am/E0sXSficPLXpwVmONpsX82IN/nk9xtmtD6ySPqIPnyA+aEX0llMBw9vMKfGsjxqESS1PmBdi3Ezq3sXF/Qt1+j+wJHvtRcfwnxF2pHNPjrON7UxLK+PItdHFNsfQQWOOi09u3sB+PdBgKLV+Y/DvjWErC1ByO26tqNxeyq2wGiRrjG4lrm/S7qdOAI8fuFU4OK0L84hxPJ8bYmc7TI5oZ4XEefPlhH237oKoiuP/Bzn5pOmObQyJ0SPlL0TyQNeepcHfcfbx91wWOEcors7yYDJFmt9o67njWt720Hx+6CuovWxXmrSuisxSQytOiyRpaR9vYryQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQd+AqfP53HVNb+Ysxxa1vfZwH/AOlfS+ZwlaxTsSulsNrXvmmGUTxPYfXd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 truncated
<tr><td class="cap"><span class="fname">7. dwg_18.3mb.dwg</span><br><span class="sub">Model · 82,393 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="dwg_18.3mb.dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHAABAAIDAQEBAAAAAAAAAAAAAAUGAwQHAgEI/8QAXRAAAQMDAwIDBAYGBgQLBQIPAQIDBAAFEQYSIRMxIkFRBxQyYRUjQnGBkRZSVpWh0iQzYrHB0UNygpIIFyU0U1RVk6LC8DWUstPh8URjc4MmZHSj4jY3RYR1tcP/xAAbAQEAAwEBAQEAAAAAAAAAAAAAAgMEBQEGB//EAEkRAAEDAgQCBwUFBgYCAgEDBQEAAhEDIQQSMUFRYQUTInGBkaEUMrHR8BVCUsHSI2JykpPhBjOCorLxQ8IkUzQWVGNEVXPi4//aAAwDAQACEQMRAD8A/MdKUr1eJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUq//AKI6P/b9n92OfzU/RHR/7fs/uxz+ar/Z38vMfNcr7Zw3B/8ATqfpVApV/wD0R0f+37P7sc/mp+iOj/2/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 truncated
<tr><td class="cap"><span class="fname">8. simple.dxf</span><br><span class="sub">— · 6 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="simple.dxf 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">9. 04manhole1-simplify.dwg</span><br><span class="sub">Layout · 7,035 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="04manhole1-simplify.dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHAABAAIDAQEBAAAAAAAAAAAAAAYHAwQFAgEI/8QAZRABAAIBAwMBBAQFCg4OCAMJAAECAwQFEQYSITETIkFRBxRhcRUWMoGRIyQzQlWUobHR0xc0NlJTVFZidJOVssHSCCU3Q2Vyc3WCpbO04vA1Y2SEkqTD1IPE8SYnREWiwuHj5P/EABoBAQADAQEBAAAAAAAAAAAAAAADBAUCAQb/xABEEQEAAQMBBQQHBAgDCAMBAAAAAQIDEQQSITFBUQUTYZEUFVJxobHRIlOBwTJCYpKi0uHwBiNyFjM0Q1STssJEguLx/9oADAMBAAIRAxEAPwD9UgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFq89dLpM2ovW9q4qWvMUrNrTERz4iPMz9kORpOoqajW7Zprbfr9Pk12G2WIz0rScPEc9t47uYmfPERE+k/KQdwcnbd/wBFuO233DS2mdFXHOT295itJiLXrbzz6R2TPPpxMTHLQjrLb5x7ZeMWqtj3DPbDhyY8U5KeMk462m9ea8Wnjjz6WiQSURHZ+vNt3jHGTbcOs1WOdXXS1vgw2y1t3RSe/upE1rWK3i0xaa2iInmOfDs33zBjz3wWw5/bRmjBFIp5tMxaYmI+McVtP5pn0B1Rx8PUWiy5NbjpGfv0eqx6TLFsNqcXveK14m0RFo96s8xM+Jh0NFqo1eO1ox3xzXtia3mvMc1rb4TP9dx+b5cTIbAAAAAAAIR1dr9Vg+kTpDR4ddm0ul1Gn11stKXitclq+w7e6JiYn8q0R4/bTx5TWLM3qppieUz5RM/k8mcJuNeueYmLine truncated
<tr><td class="cap"><span class="fname">10. 대산당진 2공구_노면_20260804_143854.dwg</span><br><span class="sub">Model · 65,495 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="대산당진 2공구_노면_20260804_143854.dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHQABAAICAwEBAAAAAAAAAAAAAAcIBQYCAwQJAf/EAEQQAQABAwMDAgQFAgQEAggHAAABAgMRBAUhBhIxB0ETIlFhCBQycYFCkRUjUqEkM3LBYrEWFyVDREVT0WOCkpSi4fH/xAAaAQEAAwEBAQAAAAAAAAAAAAAAAQIDBAUG/8QAPBEBAAEDAgQDBwIEBAUFAAAAAAECAxEhMQQSQVFhcYEFEyKRobHwMtEUQsHhFSMzciRSgtLjYnOisvH/2gAMAwEAAhEDEQA/AKxgJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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 truncated
<tr><td class="cap"><span class="fname">11. test.dwg</span><br><span class="sub">Model · 82,393 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="test.dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHAABAAIDAQEBAAAAAAAAAAAAAAUGAwQHAgEI/8QAXRAAAQMDAwIEAwUDBwUNBQIPAQIDBAAFEQYSIRMxByJBURQyYRUjQnGBUpGhFiQzYrHB0UNygpLwCBclNFNUVVaTosLS4TWUlbLT8URjc4MmZHSj4jY3RYR1tcP/xAAbAQEAAwEBAQEAAAAAAAAAAAAAAgMEBQEGB//EAEgRAAEDAgQCBwYDBgYCAgEDBQEAAhEDIQQSMUFRYQUTInGBkaEUMrHB0fBCUuEjYnKS0vEGFTOCorJDwiRTNBZUY0RVc+Lj/9oADAMBAAIRAxEAPwD8x0pSvV4lKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJS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 truncated
<tr><td class="cap"><span class="fname">12. a. 거더배치 삽도_25.02.28.dwg</span><br><span class="sub">Layout · 1,433 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="a. 거더배치 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">13. a. 교대배치 삽도_25.02.28.dwg</span><br><span class="sub">Layout · 2,138 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="a. 교대배치 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">14. a. 교량시종점 삽도_25.02.28.dwg</span><br><span class="sub">Layout · 4,432 엔티티</span><br><span class="badge b-better">개선 · 3.45 %</span><br><span class="sub">§5 참고</span></td><td><img class="shot" loading="lazy" alt="a. 교량시종점 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">15. a. 교량폭원 삽도_25.02.28.dwg</span><br><span class="sub">Layout · 2,824 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="a. 교량폭원 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">16. a. 교면포장 삽도_25.02.28.dwg</span><br><span class="sub">Layout · 1,304 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="a. 교면포장 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">17. a. 중앙분리대 삽도_25.02.28.dwg</span><br><span class="sub">Layout · 2,159 엔티티</span><br><span class="badge b-better">개선 · 18.37 %</span><br><span class="sub">§5 참고</span></td><td><img class="shot" loading="lazy" alt="a. 중앙분리대 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">18. a. 횡단경사 삽도_25.02.28.dwg</span><br><span class="sub">Layout · 5,635 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="a. 횡단경사 삽도_25.02.28.dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHQABAQEAAwEBAQEAAAAAAAAAAAYHBAUIAwIBCf/EAGYQAAEDAgIDBRAOBwQIBQIEBwABAgMEBQYRBxIhExcxVtMUFSI1OEFRVXV2k5SVs7TRFjI2N1RXYXF0kZay0tQIIzRCgZKxJFNyc1JlZqGiweHiJTNDYqSC8ERjo8MYJoOFwtXx/8QAGQEBAAMBAQAAAAAAAAAAAAAAAAECAwQF/8QAOhEBAAICAAMDCAgGAgMBAAAAAAECAxESITEEUWETFCJBkdHS8AUVYnGBkqGxMlJUY3LBZOFTgqJC/9oADAMBAAIRAxEAPwD1SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3ifHGHcMXW1Wy9XKOC4XOZsNLTo1z3vVztVFVGouq3PZrLkhSGCaXsGWrD8+HrvTpNU3e6YyoZaitq37pLqq56tia792NqZIjU6zU4cgN7I/GekfDmEK6C33Oqmmu1QxZILfRQPqKiRE7DWouWfW1lRFyXsKWBjn6O7I757Lsb1ML1rr3d5mQzzJ0aUkeq2KNOwibUXLh1U4ckAvMFY7w9jRtUlgr92npHalTTSxPhmhX/wBzHoi/JnwZoqZ7CnMg0nQtw5pf0e4po4kjdcKp9ir1jdqrO2Vv6lHJ10a5Fd/BvYQ18DpsQ4psWHNxS/Xm3W186OWFKypbDumWWeWsu3LNPrMxj0wVKvaj6vR4jM0zVMU5qieBKfThf63DWCFuFtp6dZXVMVPJWzwbsy3xSOyfUKxEzcjdmzsqmeaJksVU01lgtslwj00wNrkhTOd626SmVU25pTozr5rsR2twJmuSAaFece2mTBWJrzhS62u7VFooJapWwTtmY1zY3OYj9Rc0RVYvXTgU7rBV1mvuDbDd6pkbKivoIKqRkaKjWukja5UbmqrlmuzNVM3hvVXiT9GS8Xu6W6Ggr62xVrpWRRLG16IyRrXoi7cnNRHJ8jtmwuNFPvXYO7jUfmGAR1u020t1pkq7NgjG9yoHOc2Oqpbax8cmq5WqrV3TsopUYMxzJia6S0b8J4psyRwrNzRdaJIYnZOamojkcubuizy7CKTf6LvvKWP/ADar0iQ1Vzka1XOVGtThVVyAi8KYsrbxpIxzh6ohp2Udi5h5nkjRySP3eFXu11VVRclTZkibOydtjO73ezW2KewYemv9U+ZGOpoqmOBWM1VVX6z9i7URMvl+QyCgvWJbRp10oexfCfsi3VbZu/8A4jFSbhlTLq+3RdbWzdwcGr8pu9BJNNQ08tXT8zVD42ulg10fublTNW6ybFyXZmnDkBlty0mYwtNvqbjdtGFwp7dSxumqZm3WnescbUzc7VTauSIq5FhcMVa2i6qxda4VTOzvulPFUt//ACVla16NX5kXJfmUzjSniZukCarwPhOWWotkCJPiS7UjVkZS0zOiWCNWou6TP1ctVufAqZL0epGYww5olp8HXt9psOI4a6OgnWmdJS3RrGSJG7UV2umqiIuWetsy4dgHofAt3nxBgqw3irZFHU3ChgqpGRIqMa57EcqNzVVyzXrqp8dIGLKPBGFau/XKConpqZ0bXR06Ir1V72sTLNUThcnXOHog96nB3cik8y0gP0rL5Q27CVgttyqHR0txvEHNccaZvdSxrryq35l3P60A20isM4srbrpMxnhyeGnZR2RlE6CRiO3R+7RK92uqrkuSpsyRP4lnG9skbXxua9jkRzXNXNFReBUUwekxxhzBenrSS7E90jt6VcdtSHXY92vq0/Re1ReDWT6wN6B8KCsp7hQU1bRStmpamNs0UjeB7HIitVPnRUPuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMp/SF6XYH77Lf8A1easSmkLCHswprHFzdzHzsu1PdM9y3TdNyV3Qe2TLPW4duXYUCrMf/RifJSYMvOHqp8S1VhvVXQvazhy1tbWXPrK5z8l2cHyGwGb4m0a1k2K6nEuCsTVOGLxWsbHXatMyqp6pG7GudE9URHomzW7GezNVVQ6vTRI64Y90W2CmRrqmS9c9FVXe1jpm6zs0+VHLl/hNcIHA+jt9lxFVYmxJfKnEmJ54UpkrZ4mwxwQouepFE3NrM12qvz5Zazs74CGxS3SQ68Tphj2HLaFa1I0uSVKzZ6qa2tqdDlnnl8hgV8tjsK42nvl1rtDdFXQ07aV9tbTyyMhfr6ySpA1uukvW1uweqL9SVFfY7jR0NW+iq6imkhhqWe2he5qo16fKiqi/wADEsA1rtGFip7Nd9GF7dc4m6k1xsdEyujrclX9a6RFR6Kq5rquTYi9ZNiB9UxPPjfDF9t8GPcL3epuVpq6OktFFTcxyy1D2ZMXOaVX7MlTLJEXWzXgQ1jAFvqbRgPDdtr49yrKO201POxHI7VeyJrXJmmxclRdqGSY7rl0m2Kqs1q0XXpblNGscNxvtEyhjotbZurZFVXqrVyXVama5ddNhtGHKKqtuHrXQ3CrfW1lNSxQz1T1VXTyNYiOeue3NVRV29kDMaXR3gi24x9j9DeMRUVVPTPr47PS3Opip2Rq/Vc9urkidFns1uvwHaLoO0fy1fNVZZZq2oV2uslXcKmVXO7K60iov8TgY7oMU2rS7bcW4dw27EFIlmfbZIY62OndG9ZtfWXX4Uy7GfX4NmfK9nOkH4qKvy3TAfvAFBV0+mnSnVz0s8VLVLa9wmfGrWS6tO5Hajl2OyXYuXAUePcFw41p6Skr7tdqO3RuctRS0E+4trGrl0Eq5Zq3YuxFTPWX5MuNg7EuKrvdX09/wPPYaRIlelU+4w1CK9FREZqs27UVVz+QswMes+MqW1tqcOaIMCz3qjtcywVE0E0dHRtkRERyJNJnusibM1yVV2LmueZx8ZY7vzcK3eix9ga5YetFwpZKJ90oqqK5spd1arN0kZHquRqa2efX4E2qfPB7sR6ILdPh+qwrcsQYchqJJKC42VGTVCtkcrtSWFVa7WTNc3ps4EOXiTFuJ8dYfuNgwrgO90LrhA+jnrcQsbRQ07JGq1Xo3NzpMkVdjU2bFyXgUL3CiW7DOjm0I66QT2q3WyL/AMQ2NjkiZEn63hVERUTPhXhM8wba10qYouGNcQ0TkwytJLa7HQz5oskEiK2apcn7qyIqtTLJdVfka5dNwvh6CyYMtmHZnNraekoo6KRZY01ZmtYjVzauaZLt2beHLadzGxkUbY42tZGxEa1rUyRETgREAyvRlX3PB18Zo5xHHVVEUUb5LDdUjVzKmkZ/6UiomTZI0yTbkipqpsLine truncated
<tr><td class="cap"><span class="fname">19. 산외교- ELEVATION 산출근거도 (울산방향).dwg</span><br><span class="sub">Model · 11,262 엔티티</span><br><span class="badge b-better">개선 · 0.0047 %</span><br><span class="sub">§5 참고</span></td><td><img class="shot" loading="lazy" alt="산외교- ELEVATION 산출근거도 (울산방향).dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">20. 산외교-받침배치도 (울산방향) .dwg</span><br><span class="sub">Model · 6,240 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="산외교-받침배치도 (울산방향) .dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHAABAQADAQEBAQAAAAAAAAAAAAQDBQYCAQcI/8QAWhAAAQIEAgMLBAwKCQMEAwADAAECAwQFERIhExQxBhUiQVRVkpOU0dIXUVJhByMyNFNxdYGRlbLTFiQzN0JicqGx4iU1Q1ZkoqOz8HN0wTZEY+FFgvGDtML/xAAaAQEAAwEBAQAAAAAAAAAAAAAAAgMEAQUG/8QARREAAQIBBggLBwMEAwEBAQEAAAECAwQREiExURMiMkFSYZHRBRRCU2JxgaHS4fAVI0NykpOxMzTBY4KislTi8cIGJDX/2gAMAwEAAhEDEQA/APw3ye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eaJ4Ny9248mjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3jye7rOYpzop3mq/COt881LtT+8fhHW+eal2p/eJ4Ny924UeE9KHsd4ja+T3dZzFOdFO8eT3dZzFOdFO81X4R1vnmpdqf3j8I63zzUu1P7xPBuXu3CjwnpQ9jvEbXye7rOYpzop3k1R3Fbo6bJRZueo83BloSXfEc3JqXtdSP8I63zzUu1P7zt/Yrq1Rn5ndLCnp+bmYaUOZcjI0Zz0Rbszsq7c1JMbCe6ik/cUSqPwhJISxnqxUSadERyLb1n5mADMe4dnXfzT7kflKp/YlDjDs67+afcj8pVP7EocYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZJeNFlo8OPLxHwo0JyPZEY5WuY5FuioqZoqLxn7FucqW6yR3Q0ibqW7erPkYU7SHx2x5+KkNYc2zSriVz7YWtaqLfJQD8ZM0SVmITFfFgRWNTjcxUQ8zL0iTEV7fcueqp9J+v1VlLnJDdHJ7lp6htpEdujdM4KtHjpLtjMiMV6LDdDa9VhsutkTNUS1wD8eiw3wnqyKxzHpta5LKh7dLx2xGw3QYiRHtR7Wq1bq1UuionmVMzpN3lRkZ6PJNkIzYroMJGxVbIQYCIuFv9oxyrG2Lwnoi/Sp+g02Xl90FNkqjS6ZITzpWmwpOJEZI1OLNNjQ5dGK1FhtWBe6Ja+VlRVAPxqNLxoDIL40GJDZHZpITntVEiNxK3E1eNMTXJdONFTiLKRQ6tWdNvPS56f0KIsXVZd8XR3vbFhRbXsu3zKdPu+a6R3O7kKVPUl0pU4FOc6LFjsiw4zUWbmlSGrHKjcNnI6+G+e22Rn9jielaXDhTFamqW2krMYnyqUyWnZyP7lHIixIblhstbNyptVWNctwDhULine truncated
<tr><td class="cap"><span class="fname">21. 산외교_파이형_교각일반도(울산P11-꺾임).dwg</span><br><span class="sub">Model · 25,927 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="산외교_파이형_교각일반도(울산P11-꺾임).dwg 0.4.1" src="data:image/jpeg;base64,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 truncated
<tr><td class="cap"><span class="fname">22. 산외교_파이형_교각일반도(울산P9).dwg</span><br><span class="sub">Model · 26,207 엔티티</span><br><span class="badge b-same">픽셀 동일</span></td><td><img class="shot" loading="lazy" alt="산외교_파이형_교각일반도(울산P9).dwg 0.4.1" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAMgBQADASIAAhEBAxEB/8QAHAABAAIDAQEBAAAAAAAAAAAAAAQFAwYHAgEI/8QAahAAAQMCAwIEDBEIBQkGBAQHAQACAwQRBRIhBjETFEFRBxUWIlRVYXGTlNHSFyMyNTY3U3N0dYGRkrGys9MzQlJWcoKVoSQ0oqPBJSZDRGJm4eLwOGR2g7TCCGO18UZHV8PEGGWEhaTj/8QAGwEBAAMBAQEBAAAAAAAAAAAAAAIDBAEFBgf/xABPEQABAwEDBwcKBAMHBAIBBAMBAAIDEQQSIRMxQVFhcZEFFDJSobHRIjRTcoGSwdLh8DNCYrIVFiMGQ1SCosLxJHOT4mOjNSVEZMOEs/L/2gAMAwEAAhEDEQA/APzGiIuriIiIiIiIiIiIiK82F9m+z3xjT/etVGrzYX2b7PfGNP8AetU4+mN6zW3zeT1T3K16L/tkY374z7tq05bj0X/bIxv3xn3bVpylP+K7eVRyT5hB6jf2hFmpaqeke99NNJE58bonFjrZmOBa5p7hBIWFFUvQUiOsqYzGWTyelsMbAXXAYSSW25iXE23annX1tfVNrYaxlRI2phc10UjTYxlvqctt1rC1tyjIiIptHildRshbS1MkQglM8WU/k5Dlu9vM7rW6j9EcyhIiL61zmOu0lp5wbL1FI+GVkkTi17CHNI5CF4REWWeokny8K64boAAAB8gSaommjgjlkc9kDDHE1xuGNzF1hzDM5x75KxIiIiIiIiIiIiIiIiIiIp2DxGaryij42Mpuyzzl7vWkHufKoKyUzmNnjMweYswzhhsS2+tlZEQ14J++9WQuDZAXZvvYe5bI/CmmKOaXDhSt4pNI4Fz23kDZLCz3Em2QGw59dFEw6mpy7CY5KJkwq3ASSOc8EXkLdLEDcF9fU07Gzl1RROiMb2xsp4XMkBLSB12UG2uuZxuL71AoRC+knZJVNp5s7DG5+e2Wzsw60Hly8nIvSc+IPF0D/TopspjQ03r2HvhEjbjW6c92mFNlMaEDepOK0EFJR0ZhcXuklkDnktJsAyw61zhynu6qTW0MkFbURQ4C+SOORzGvyzHMAbA6GyrpTDFFTwyTx1dOx73ltOXMcC4NG97P9kch5V643QcFwfFa3Lmzf1tv4arvwhzswzbcwx0EYlU34A52AGamnMMcbrhiVWnebiyLJOYnSuMDHsj5GveHEfKAPqWNecRQryiKGgRERcXERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERF9aMzgL2ubLreE0cg6KO0dFh8oa2iM2FRU8UVSakUzCYs0T4IZMjw1ozPI1zuuHBzr8jW30m1VCzaaTGsQwptfLVU9qlknBn+kG2aZvCskYS62Y5mEAyOAAs0oi3/AGv2S6ndla+hZNUUVDViCaaXEzXVMTTYPZktRRsZL12UkkuF3M627gtNp48Hi2Mfs7JiMLMYrpo8TdUCTNTRuYxzYqZ7gDZ5bLI4vBLWuLGut15Z42g21oMQwOsoMPwmagfUhjXvZxJj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 truncated
</tbody></table></div>
<h2>7. 파싱 데이터 비교</h2>
<p>Node 에서 두 wasm 으로 같은 DWG 21개를 파싱해 엔티티를 <code>타입#handle</code> 로 짝지은 뒤 필드별로 비교했다. 파일별 엔티티 수와 handle 집합은 완전히 같고, 값이 바뀐 필드는 아래가 전부다.</p>
<div class="tbl"><table>
<thead><tr><th>바뀐 값</th><th class="num">필드 변경 건수</th><th class="num">파일 수</th><th>원인</th><th>화면 영향</th></tr></thead>
<tbody>
<tr><td>치수 정의점 <code>pt10</code></td><td class="num">1,175</td><td class="num">12</td><td>0.4.1 이 (0,0,0) 으로 냄 → 실제 좌표</td><td>블록 없는 치수(대체 렌더)의 선택 범위·extents 만</td></tr>
<tr><td>ATTDEF 정렬점·정렬·폭 비율</td><td class="num">2,171</td><td class="num">14</td><td>0.4.1 이 읽지 못함 → 실제 값</td><td>블록 안 속성 텍스트 위치·폭이 정확해짐</td></tr>
<tr><td>익명 블록 이름</td><td class="num">812</td><td class="num">1</td><td>번호 체계 변경 (<code>*U1</code> → <code>*U7</code>)</td><td>없음 — 렌더는 handle 기준, 이름·블록 테이블 불일치 0건</td></tr>
<tr><td>트루컬러 엔티티의 근사 ACI</td><td class="num">116</td><td class="num">3</td><td>근사 계산 개선 (원본 RGB 는 동일)</td><td>원본 색에 더 가까워짐</td></tr>
<tr><td>VIEWPORT id 0 → 1</td><td class="num">27</td><td class="num">10</td><td>0.6.5 가 레이아웃 전체 뷰포트에 id 1 부여</td><td>전체 뷰포트 오판 해소 (중앙분리대 검은 띠)</td></tr>
<tr><td>VIEWPORT 상태 비트</td><td class="num">26</td><td class="num">2</td><td>비트 0x10000 추가</td><td>없음 (Viewer2D 는 isOn 만 사용)</td></tr>
<tr><td>3D 폴리선 점 순서</td><td class="num">7</td><td class="num">1</td><td>0.4.1 이 vertex 를 handle 순으로 정렬</td><td>가짜 직선 제거 (dwg_1.60mb)</td></tr>
<tr><td>텍스트 내용</td><td class="num">1</td><td class="num">1</td><td>CP949 기호 디코딩 (<code>500¡¿350</code> → <code>500×350</code>)</td><td>깨진 기호 1건 해소</td></tr>
<tr><td>OLE 데이터 길이</td><td class="num">1</td><td class="num">1</td><td>페이로드 재조립으로 512 B 차이</td><td>없음 (추출 이미지 바이트 동일)</td></tr>
</tbody></table></div>
<p><strong>한글</strong>: 0.4.1 은 평면및종단면도(153개)와 굴착및시공순서도(160개)의 한글을 Latin-1 로 깨진 채 내보냈고, 뷰어의 JS 보정(<code>fixDwgKoreanText</code>)이 복원해 왔다. 0.6.5 는 DWG 21개 전부 처음부터 정상 디코딩한다(깨짐 0). 보정 후 한글 텍스트 수는 두 버전이 모든 파일에서 같다.</p>
<h2>8. 업그레이드에서 바꾼 것</h2>
<p>acadrust 는 crates.io 의 0.6.5 를 <strong>고치지 않고</strong> 쓴다 (<code>acadrust = "=0.6.5"</code>). 0.6.5 에 맞추느라 바꾼 곳은 전부 우리 래퍼 <code>dwg-wasm</code>(MIT) 안이다.</p>
<div class="tbl"><table>
<thead><tr><th>변경</th><th>이유</th></tr></thead>
<tbody>
<tr><td>vendored <code>rust/acadrust/</code>(189개 파일) 삭제, crates.io 버전 고정</td><td>무수정 사용. 고지에 적은 버전과 빌드 소스를 일치시킨다</td></tr>
<tr><td>손상 레코드 허용 모드(<code>failsafe</code>)로 읽기</td><td>0.6.5 기본 모드는 레코드 하나만 깨져도 도면 전체를 거부한다. <code>a. 거더배치 삽도</code> 가 통째로 열리지 않았다. 허용 모드에서는 정상으로 열리고, 건너뛴 레코드는 알림으로 남는다</td></tr>
<tr><td>wasm 메모리를 32 MB 단위로 확장하는 할당자</td><td>그대로 올리면 37 MB 노면 도면 파싱이 3.0 초 → 7.4 초로 느려졌다. 원인은 브라우저 엔진(V8)에서 메모리를 늘리는 비용이 현재 메모리 크기에 비례하는데, 0.6.5 가 64 KB 단위로 수천 번 늘렸기 때문이다 (프로파일로 확인). 수정 후 3.3 초</td></tr>
<tr><td>API 변경 대응 (치수 Box 타입, OLE 페이로드)</td><td>컴파일 에러 9개. OLE 이미지 추출 결과는 기존과 바이트 단위로 같다</td></tr>
</tbody></table></div>
<h2>9. 성능·크기</h2>
<div class="tbl"><table>
<thead><tr><th>항목</th><th class="num">0.4.1 + 패치</th><th class="num">0.6.5</th></tr></thead>
<tbody>
<tr><td>wasm 크기 (원본 / brotli 압축)</td><td class="num">864 KB / 294 KB</td><td class="num">2,976 KB / 815 KB</td></tr>
<tr><td>브라우저 로드 — 대산당진 노면 (37 MB)</td><td class="num" colspan="2">5,651 → 5,737 ms</td></tr>
<tr><td>브라우저 로드 — dwg_18.3mb (18 MB)</td><td class="num" colspan="2">3,920 → 4,024 ms</td></tr>
<tr><td>Node 파싱만 — 노면 / dwg_18.3mb</td><td class="num">3.0 s / 1.9 s</td><td class="num">3.3 s / 2.1 s</td></tr>
<tr><td>wasm 메모리 — 노면 / dwg_18.3mb</td><td class="num">672 / 546 MB</td><td class="num">773 / 505 MB</td></tr>
</tbody></table></div>
<p>크기가 커진 것은 acadrust 0.6 이 DXF/DWG 쓰기, ACIS 등을 포함해 라이브러리 자체가 커졌기 때문이다. 끌 수 있는 기능 옵션은 없다. 크기 우선 최적화(<code>opt-level = "z"</code>)도 시험했으나 815 → 742 KB(−9 %)를 얻는 대신 파싱이 36 % 느려져 채택하지 않았다.</p>
<h2>10. 라이선스 영향</h2>
<ul>
<li>0.4.1 은 acadrust 를 2개 파일 3곳 고쳐 쓰고 있었고, 공개한 패치는 원본에 적용되지 않아 배포 wasm 의 소스를 재현할 수 없었다 (MPL-2.0 §3.2 미충족).</li>
<li>0.6.5 는 무수정이므로 MPL-2.0 의무가 <strong>라이선스 원문 동봉 + 소스 입수 위치 고지</strong>로 줄어든다. 고지에는 crates.io 다운로드 주소, upstream 커밋, crate SHA-256(빌드에 쓴 <code>Cargo.lock</code> checksum 과 일치)을 적었다.</li>
<li>공개 배포본(pages.dev)은 재빌드·재배포 전까지 옛 고지(0.4.1 패치)를 보여 준다.</li>
</ul>
<h2>11. 남은 것</h2>
<ul>
<li>pages.dev 재배포 (현재 공개본은 0.4.1 wasm + 옛 고지)</li>
<li>뷰어가 0.6.5 에서 새로 읽히는 호 길이 치수·대형 반경 치수(<code>DIMENSION_ARC</code>, <code>DIMENSION_LARGE_RADIAL</code>)를 아직 그리지 않는다. 샘플 22개에는 해당 엔티티가 없다.</li>
<li>XDATA 는 acadrust 가 읽지만 뷰어 출력에는 넣지 않는다 (업그레이드 전과 같음).</li>
<li>wasm 에 들어가는 Rust 의존 라이브러리(MIT/Apache/BSD 등)의 고지 생성.</li>
</ul>
<h3>검증하지 못한 것</h3>
<div class="tbl"><table><thead><tr><th>항목</th><th>이유</th></tr></thead><tbody>
<tr><td>AutoCAD 원본 화면과의 대조</td><td>같은 위치의 AutoCAD 정답 캡처가 없다. 개선 판정은 데이터 근거(원본 RGB, vertex 좌표의 연속성, 뷰포트 id·배율)에 기댄다</td></tr>
<tr><td>Firefox / Safari 에서의 로드 시간</td><td>Chrome 과 Node 에서만 측정</td></tr>
<tr><td>Layout/Model 탭을 바꾼 뒤의 화면, 2.5D 보기</td><td>기본 화면과 지정 확대 화면만 캡처</td></tr>
</tbody></table></div>
</main>
<div id="lb" role="dialog" aria-label="확대 이미지"><img alt=""></div>
<script>
(function () {
var root = document.documentElement, KEY = 'report-theme';
try { var t = localStorage.getItem(KEY); if (t) root.setAttribute('data-theme', t); } catch (e) {}
document.getElementById('theme').addEventListener('click', function () {
var cur = root.getAttribute('data-theme') ||
(matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
var next = cur === 'dark' ? 'light' : 'dark';
root.setAttribute('data-theme', next);
try { localStorage.setItem(KEY, next); } catch (e) {}
});
var lb = document.getElementById('lb'), lbImg = lb.querySelector('img');
document.addEventListener('click', function (e) {
var img = e.target.closest && e.target.closest('img.shot');
if (img) { lbImg.src = img.src; lbImg.alt = img.alt; lb.classList.add('open'); }
else if (e.target === lb || e.target === lbImg) lb.classList.remove('open');
});
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') lb.classList.remove('open'); });
})();
</script>
</body>
</html>
+115
View File
@@ -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>` 으로 바뀜 |
| `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% 가 `<dlmalloc::sys::System as Allocator>::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 패치)를 보여 준다.
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

@@ -0,0 +1,414 @@
{
"01-korean": {
"1before": {
"snap": "95fa6a4",
"file": "civil.dwg",
"loadMs": 5230,
"status": "✓ civil.dwg · 17807 entities",
"ok": true,
"space": "n/a (no spaces API)",
"zoom": {
"camX": 600800,
"camY": 478560,
"width": 7000,
"up": [
0,
1
]
},
"image": "01-korean-1before.jpg",
"errors": []
},
"2after": {
"snap": "be8d52f",
"file": "civil.dwg",
"loadMs": 5650,
"status": "✓ civil.dwg · 17810 entities · Layout",
"ok": true,
"space": "model 1f",
"zoom": {
"camX": 598950,
"camY": 478462,
"width": 90,
"up": [
0,
1
]
},
"image": "01-korean-2after.jpg",
"errors": []
},
"3current": {
"snap": "current",
"file": "civil.dwg",
"loadMs": 775,
"status": "✓ civil.dwg · 17810 entities · Layout",
"ok": true,
"space": "model 1f",
"zoom": {
"camX": 598950,
"camY": 478462,
"width": 90,
"up": [
0,
1
]
},
"image": "01-korean-3current.jpg",
"errors": []
}
},
"02-model-paper": {
"1before": {
"snap": "95fa6a4",
"file": "civil.dwg",
"loadMs": 5041,
"status": "✓ civil.dwg · 17807 entities",
"ok": true,
"image": "02-model-paper-1before.jpg",
"errors": []
},
"2after": {
"snap": "be8d52f",
"file": "civil.dwg",
"loadMs": 5012,
"status": "✓ civil.dwg · 17810 entities · Layout",
"ok": true,
"image": "02-model-paper-2after.jpg",
"errors": []
},
"3current": {
"snap": "current",
"file": "civil.dwg",
"loadMs": 797,
"status": "✓ civil.dwg · 17810 entities · Layout",
"ok": true,
"image": "02-model-paper-3current.jpg",
"errors": []
}
},
"03-large-hatch": {
"3current": {
"snap": "current",
"file": "dwg_18.3mb.dwg",
"loadMs": 3693,
"status": "✓ dwg_18.3mb.dwg · 82393 entities · Model",
"ok": true,
"image": "03-large-hatch-3current.jpg",
"errors": []
},
"1before": {
"snap": "7a6edd4",
"file": "dwg_18.3mb.dwg",
"loadMs": 213769,
"status": "✓ dwg_18.3mb.dwg · 82393 entities · Model",
"ok": true,
"image": "03-large-hatch-1before.jpg",
"errors": []
},
"2after": {
"snap": "b047dc4",
"file": "dwg_18.3mb.dwg",
"loadMs": 3597,
"status": "✓ dwg_18.3mb.dwg · 82393 entities · Model",
"ok": true,
"image": "03-large-hatch-2after.jpg",
"errors": []
}
},
"04-slug-text": {
"3current": {
"snap": "current",
"file": "BasicSample.dwg",
"loadMs": 529,
"status": "✓ BasicSample.dwg · 7309 entities · Model",
"ok": true,
"space": "model 2",
"zoom": {
"camX": 2900,
"camY": 1900,
"width": 1100,
"up": [
0,
1
]
},
"image": "04-slug-text-3current.jpg",
"errors": []
},
"1before": {
"snap": "b047dc4",
"file": "BasicSample.dwg",
"loadMs": 524,
"status": "✓ BasicSample.dwg · 7309 entities · Model",
"ok": true,
"space": "model 2",
"zoom": {
"camX": 2900,
"camY": 1900,
"width": 1100,
"up": [
0,
1
]
},
"image": "04-slug-text-1before.jpg",
"errors": []
},
"2after": {
"snap": "fb8f7ca",
"file": "BasicSample.dwg",
"loadMs": 531,
"status": "✓ BasicSample.dwg · 7309 entities · Model",
"ok": true,
"space": "model 2",
"zoom": {
"camX": 2900,
"camY": 1900,
"width": 1100,
"up": [
0,
1
]
},
"image": "04-slug-text-2after.jpg",
"errors": []
}
},
"05-mesh": {
"3current": {
"snap": "current",
"file": "대산당진 2공구_노면_20260804_143854.dwg",
"loadMs": 5300,
"status": "✓ 대산당진 2공구_노면_20260804_143854.dwg · 65495 entities · Model",
"ok": true,
"space": "model 70",
"zoom": {
"camX": 156542.00000000003,
"camY": 479804.00000000006,
"width": 160,
"up": [
0,
1
]
},
"image": "05-mesh-3current.jpg",
"errors": []
},
"1before": {
"snap": "6f200ef",
"file": "대산당진 2공구_노면_20260804_143854.dwg",
"loadMs": 5030,
"status": "✓ 대산당진 2공구_노면_20260804_143854.dwg · 65486 entities · Model",
"ok": true,
"space": "model 70",
"zoom": {
"camX": 156542.00000000003,
"camY": 479804.00000000006,
"width": 160,
"up": [
0,
1
]
},
"image": "05-mesh-1before.jpg",
"errors": []
},
"2after": {
"snap": "c67a803",
"file": "대산당진 2공구_노면_20260804_143854.dwg",
"loadMs": 5279,
"status": "✓ 대산당진 2공구_노면_20260804_143854.dwg · 65495 entities · Model",
"ok": true,
"space": "model 70",
"zoom": {
"camX": 156542.00000000003,
"camY": 479804.00000000006,
"width": 160,
"up": [
0,
1
]
},
"image": "05-mesh-2after.jpg",
"errors": []
}
},
"06-lineweight": {
"3current": {
"snap": "current",
"file": "대산당진 2공구_노면_20260804_143854.dwg",
"loadMs": 5347,
"status": "✓ 대산당진 2공구_노면_20260804_143854.dwg · 65495 entities · Model",
"ok": true,
"space": "model 70",
"zoom": {
"camX": 156542.00000000003,
"camY": 479804.00000000006,
"width": 160,
"up": [
0,
1
]
},
"image": "06-lineweight-3current.jpg",
"errors": []
},
"1before": {
"snap": "eec3382",
"file": "대산당진 2공구_노면_20260804_143854.dwg",
"loadMs": 5068,
"status": "✓ 대산당진 2공구_노면_20260804_143854.dwg · 65495 entities · Model",
"ok": true,
"space": "model 70",
"zoom": {
"camX": 156542.00000000003,
"camY": 479804.00000000006,
"width": 160,
"up": [
0,
1
]
},
"image": "06-lineweight-1before.jpg",
"errors": []
},
"2after": {
"snap": "1f80442",
"file": "대산당진 2공구_노면_20260804_143854.dwg",
"loadMs": 5220,
"status": "✓ 대산당진 2공구_노면_20260804_143854.dwg · 65495 entities · Model",
"ok": true,
"space": "model 70",
"zoom": {
"camX": 156542.00000000003,
"camY": 479804.00000000006,
"width": 160,
"up": [
0,
1
]
},
"image": "06-lineweight-2after.jpg",
"errors": []
}
},
"07-layer-toggle": {
"3current": {
"snap": "current",
"file": "dwg_18.3mb.dwg",
"loadMs": 3698,
"status": "✓ dwg_18.3mb.dwg · 82393 entities · Model",
"ok": true,
"toggle": {
"layer": "CF-PATT",
"hideMs": [
21,
18,
13
],
"showMs": [
35,
5,
5
]
},
"errors": []
},
"1before": {
"snap": "fb8f7ca",
"file": "dwg_18.3mb.dwg",
"loadMs": 3703,
"status": "✓ dwg_18.3mb.dwg · 82393 entities · Model",
"ok": true,
"toggle": {
"layer": "CF-PATT",
"hideMs": [
565,
454,
512
],
"showMs": [
501,
622,
609
]
},
"errors": []
},
"2after": {
"snap": "3480945",
"file": "dwg_18.3mb.dwg",
"loadMs": 3603,
"status": "✓ dwg_18.3mb.dwg · 82393 entities · Model",
"ok": true,
"toggle": {
"layer": "CF-PATT",
"hideMs": [
18,
17,
13
],
"showMs": [
26,
5,
6
]
},
"errors": []
}
},
"n1-percent": {
"3current": {
"snap": "current",
"file": "C0060203-001-표준단면도(2차로,자연환기300m이상).dwg",
"loadMs": 528,
"status": "✓ C0060203-001-표준단면도(2차로,자연환기300m이상).dwg · 2068 entities · Model",
"ok": true,
"space": "model 2",
"zoom": {
"camX": 12700,
"camY": 16740,
"width": 2600,
"up": [
0,
1
]
},
"image": "n1-percent-3current.jpg",
"errors": []
}
},
"n2-cp949-symbol": {
"3current": {
"snap": "current",
"file": "civil.dwg",
"loadMs": 820,
"status": "✓ civil.dwg · 17810 entities · Layout",
"ok": true,
"space": "model 1f",
"zoom": {
"camX": 162366.6,
"camY": 475780,
"width": 9,
"up": [
0,
1
]
},
"image": "n2-cp949-symbol-3current.jpg",
"errors": []
}
},
"n3-fit-crop": {
"3current": {
"snap": "current",
"file": "산외교- ELEVATION 산출근거도 (울산방향).dwg",
"loadMs": 738,
"status": "✓ 산외교- ELEVATION 산출근거도 (울산방향).dwg · 11262 entities · Model",
"ok": true,
"image": "n3-fit-crop-3current.jpg",
"errors": []
}
}
}
+53 -101
View File
@@ -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)
File diff suppressed because it is too large. Load diff
+418
View File
@@ -0,0 +1,418 @@
# 샘플 테스트·오류 처리 현황 보고서 (2026-10-19)
> 대상: `dwg-dxf-viewer-sample` (HEAD `1f80442` + 미커밋 작업 트리)
> 근거: 이번 재테스트 실측, git 이력 20커밋, `docs/*.md` 10건, `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 → 13~35ms
- 그 외 회색 원 제거, 메쉬 표시, 선가중치 적용, 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. 권장 액션
1. **라이선스.**
- MPL 패치를 다시 만든다. 원본 0.4.1 과 실제 vendored 트리의 전체 diff 로 만들고, 원본에 적용해서 성공하는지 확인한다.
- 고지 문서 4곳의 "한 파일만 수정", "unmodified" 문구를 고친다.
- `ICAD_LIN` 은 IntelliCAD(ITC) 계약 범위를 확인한다. 외부 배포가 허용되지 않으면 제거한다.
2. **미커밋 작업 정리.**
- 2.5D 보기, VIEWPORT 채움 변환, Z 붕괴 수정을 커밋하거나 분리한다.
- 루트의 untracked 대용량 파일(`C0060202.json` 31.7MB, `SAN01.json` 16.6MB, `C0060202.zip`)은 `.gitignore` 에 넣거나 삭제한다.
3. **e2e 를 실제 테스트로.**
- `linParser.ts` 의 확장자 없는 import 를 고친다.
- 샘플 경로를 `dist/` 에서 `public/samples/` 로 바꾼다.
- assert 를 추가한다.
- 이번에 쓴 브라우저 e2e 와 3단 비교 스크립트를 레포에 넣는다.
4. **Fit 잘림 수정** (§3.4-①).
5. **텍스트 후처리 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`](../src/viewer2d/Viewer2D.js) 의 `stripMText` 는 `%%d`, `%%p`, `%%c` 만 처리한다.
**③ 기호만 있는 CP949 문자열이 깨진 채 남음.** `원인 확정`.
- civil 에 `500¡¿350` 이 표시된다. CP949 로 디코딩하면 `500×350` 이다.
- [`fixDwgKoreanText.ts:64-67`](../src/viewer2d/fixDwgKoreanText.ts) 는 디코딩 결과에 한글이 생길 때만 변환을 받아들인다.
**④ 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 = viewer` 1줄
- 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` | 현재 |
|---|---|
| ![](images/sample-test-2026-10-19/01-korean-2after.jpg) | ![](images/sample-test-2026-10-19/01-korean-3current.jpg) |
**② Model/Paper 겹침, Layout 비어 보임** (`civil.dwg`, 로드 직후 기본 화면)
| 수정 전 `95fa6a4` | 수정 후 `be8d52f` | 현재 |
|---|---|---|
| ![](images/sample-test-2026-10-19/02-model-paper-1before.jpg) | ![](images/sample-test-2026-10-19/02-model-paper-2after.jpg) | ![](images/sample-test-2026-10-19/02-model-paper-3current.jpg) |
| 점 3개만 보임. Model(x≈600k·162k)과 Paper(원점)를 한꺼번에 Fit 함 | Layout 이 열리고 VIEWPORT 내용이 투영됨 | 같음 (밝은 종이 배경) |
**③ 대용량 로딩 + 거대 회색 원** (`dwg_18.3mb.dwg`, 로드 직후 기본 화면)
| 수정 전 `7a6edd4` | 수정 후 `b047dc4` | 현재 |
|---|---|---|
| ![](images/sample-test-2026-10-19/03-large-hatch-1before.jpg) | ![](images/sample-test-2026-10-19/03-large-hatch-2after.jpg) | ![](images/sample-test-2026-10-19/03-large-hatch-3current.jpg) |
| 로드 **213.8초**. 회색 SOLID HATCH 가 도면 아래쪽 절반을 덮음 | **3.6초**, 회색 채움 없음 | **3.7초** |
**④ Slug 텍스트 크기** (`BasicSample.dwg`, "정면도" h=140 주변 고정 화면)
| 수정 전 `b047dc4` | 수정 후 `fb8f7ca` | 현재 |
|---|---|---|
| ![](images/sample-test-2026-10-19/04-slug-text-1before.jpg) | ![](images/sample-test-2026-10-19/04-slug-text-2after.jpg) | ![](images/sample-test-2026-10-19/04-slug-text-3current.jpg) |
| 글자 높이 **150px** | **202px** | **202px** |
- 자홍색 픽셀 bbox 높이를 쟀다. 비율 150/202 = **0.743** 으로, 커밋 메시지 "3.6 → 2.68 (0.744)" 와 일치한다.
- 주변 선과 치수의 위치는 세 장 모두 같다.
**⑤ SubDMesh(MESH) 미표시** (노면 도면, 연결부 (156542, 479804), 폭 160)
| 수정 전 `6f200ef` | 수정 후 `c67a803` | 현재 |
|---|---|---|
| ![](images/sample-test-2026-10-19/05-mesh-1before.jpg) | ![](images/sample-test-2026-10-19/05-mesh-2after.jpg) | ![](images/sample-test-2026-10-19/05-mesh-3current.jpg) |
| 삼각망 없음 | 도로면·부체도로면 삼각망 표시 | 같음 |
c67a803 에는 선가중치 수정도 함께 들어 있다.
**⑥ 선가중치** (⑤와 같은 화면)
| 수정 전 `eec3382` | 수정 후 `1f80442` (11 px/mm) | 현재 |
|---|---|---|
| ![](images/sample-test-2026-10-19/06-lineweight-1before.jpg) | ![](images/sample-test-2026-10-19/06-lineweight-2after.jpg) | ![](images/sample-test-2026-10-19/06-lineweight-3current.jpg) |
| 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) |
|---|---|---|
| ![](images/sample-test-2026-10-19/n1-percent-3current.jpg) | ![](images/sample-test-2026-10-19/n2-cp949-symbol-3current.jpg) | ![](images/sample-test-2026-10-19/n3-fit-crop-3current.jpg) |
| `-2 %%%` (정답 `-2 %`) | `500¡¿350` (정답 `500×350`) | 왼쪽 잘림, 오른쪽 약 470px 공백 |
---
## 5. 남은 과제
### A. 우선 처리
| # | 과제 | 근거 |
|---|---|---|
| A-1 | **MPL 패치가 실제 소스를 재현하지 못함** (`원인 확정`)<br>- `public/licenses/acadrust-0.4.1-read_mesh.patch` 를 원본 acadrust 0.4.1 crate 에 `git apply --check` 하면 `entities.rs:2350`(read_ole2frame)에서 실패한다.<br>- 고지의 "One file differs", "exact Source Code Form" 문구와 `acadrust-dwg/package.json` 의 "used unmodified" 가 사실과 다르다. | 이번 실행, `THIRD-PARTY-NOTICES.md` |
| A-2 | **Visio 저작권 데이터가 번들됨**<br>- `linData.ts` 의 `ICAD_LIN` 헤더가 "Copyright (c) 1998 by Visio Corporation. All rights reserved" 다.<br>- `linParser.ts:228` 이 import 될 때 등록하므로 배포본에 반드시 들어간다.<br>- 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_dwg` export 미정리
- 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` 핵심:
```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 로딩:
1. **기본**: glue 의 `new URL('./acadrust_dwg_bg.wasm', import.meta.url)` 패턴을 유지한다.
2. **탈출구**: `init({ wasm })` 로 URL, bytes, Module 을 직접 넘길 수 있게 한다.
3. **Node**: `initSync({ module: readFileSync(...) })`. `scripts/parse-dwg.mjs` 에서 동작을 확인했다.
### 6.4 작업 순서
1. 라이선스 L1~L4 해결
2. 정본 레포 통일, `rust/dwg-wasm` 과 vendored acadrust 이전, `rust-toolchain.toml` 로 툴체인 고정
3. 파서 분리: `?url` 제거, `init({ wasm })` 추가, Node 진입점, `parseCad()`, 상대 import 에 `.js`
4. Viewer2D: 생성자 옵션(`fontUrl`, `keyboard` 등), `dispose()`, `ResizeObserver`, `localStorage` 잔재 제거, 콜백 해제 함수
5. 타입: 수기 `Viewer2D.d.ts` 보완, `CadParseResult` 구체화
6. 빌드: tsup/rollup/tsc 로 ESM, wasm 은 파일로 복사, `opentype.js` 는 default import (Node ESM 에서 named import 실패 실측)
7. 검증: 소비 예제(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/wasm` MIME 이 아니면 느린 폴백으로 떨어진다.
- **한글**: `cp949`/`euc-kr` TextDecoder 가 없는 런타임에서는 `fixDwgKoreanText` 가 아무 표시 없이 보정을 건너뛴다.
- **버전 정책**: 두 패키지는 lockstep 으로 올린다. `CadParseResult` 필드 추가는 minor, 삭제나 변경은 major.
- **upstream drift**: README 의 "본가에서 다시 복사" 절차를 따르면 이 레포의 기능(lineweight, 2.5D, Model/Layout)이 지워진다.
- **acadrust 버전**: 상류는 0.6.x 다. 0.4.1 fork 유지 여부를 결정해야 한다.
- **릴리스**: 깨끗한 태그에서만 배포한다.
---
## 7. 재현 방법
```powershell
# 헤드리스 파싱 (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) |
+26 -2
View File
@@ -65,6 +65,9 @@
button:hover, label.btn:hover { border-color: var(--accent); }
button.primary { background: #238636; border-color: #2ea043; }
button.wasm { border-color: var(--wasm); color: var(--wasm); }
/* 켜져 있는 토글 버튼 (2.5D 보기 등) */
#toolbar > button.on { background: #1f6feb; border-color: #58a6ff; color: #fff; }
.opt-row.disabled { opacity: .45; pointer-events: none; }
label.btn input { display: none; }
/* 옵션 패널 — 값은 IndexedDB(hmw-viewer/options)에 저장된다 */
#optBody { padding: 12px 14px; overflow: auto; font-size: 12px; color: var(--ink); }
@@ -232,6 +235,7 @@
<button id="sampleDxf" class="primary" type="button" title="dxf-parser">Sample DXF</button>
<div id="spaces" title="Model Space / Paper Space (Layout)"></div>
<button id="fit" type="button">Fit (F)</button>
<button id="view25Btn" type="button" title="2.5D 보기 — Top 뷰를 풀고 기울여서 등고선 등의 높낮이(Z)를 본다. 왼쪽 드래그=회전, 가운데/오른쪽 드래그=이동">2.5D 보기</button>
<button id="theme" type="button">Theme</button>
<button id="optionsBtn" type="button" title="표시 옵션 (선가중치 · 그리드 · 줌)">옵션</button>
<button id="layersBtn" type="button">Layers</button>
@@ -311,6 +315,26 @@
<input id="optZoomSpeedNum" type="number" min="0.1" max="5" step="0.1" value="1" />
</div>
</div>
<div class="opt-sec">
<h4>2.5D 보기</h4>
<div class="opt-row">
<label for="opt25D">기울여 보기 (Top 해제)</label>
<input id="opt25D" type="checkbox" />
</div>
<div id="optZRow" class="opt-row disabled">
<label for="optZScale">높이 과장 (Z)</label>
<input id="optZScale" type="range" min="1" max="50" step="0.5" value="1" />
<input id="optZScaleNum" type="number" min="1" max="200" step="0.5" value="1" />
<span class="opt-unit">×</span>
</div>
<p class="opt-help">
도면은 이미 CAD 표고(Z)를 그대로 갖고 있다. 2.5D 는 같은 직교 카메라를
남동 등각(SE Isometric)으로 돌려 그 높낮이를 보여준다 — 재파싱 없음.
부지가 넓고 기복이 작아 평평하게 보이면 Z 과장을 올린다.
<b>왼쪽 드래그 = 회전, 가운데·오른쪽 드래그 = 이동.</b>
</p>
</div>
</div>
</div>
@@ -341,10 +365,10 @@
지도: <a href="/docs/modules-dwg-dxf.html" target="_blank">docs/modules-dwg-dxf.html</a>
</p>
<!-- MPL-2.0 §3.2(b): recipients of the wasm must be told where the
acadrust source (with our local patch) can be obtained. -->
acadrust source can be obtained (unmodified 0.6.5, see the notice). -->
<p style="margin:6px 0 0">
오픈소스 고지: <a href="/licenses/THIRD-PARTY-NOTICES.md" target="_blank">THIRD-PARTY-NOTICES</a>
(acadrust · MPL-2.0 · <a href="/licenses/acadrust-0.4.1-read_mesh.patch" target="_blank">local patch</a>)
(acadrust 0.6.5 · MPL-2.0 · <a href="https://crates.io/crates/acadrust/0.6.5" target="_blank" rel="noopener">source</a>)
</p>
</aside>
+15 -24
View File
@@ -10,43 +10,34 @@ Served copies of the license texts live under
---
## acadrust 0.4.1 — Mozilla Public License 2.0 — **MODIFIED**
## acadrust 0.6.5 — Mozilla Public License 2.0 — unmodified
| | |
|---|---|
| Component | `acadrust` (DWG/DXF parser, Rust) |
| Version | 0.4.1 |
| Version | 0.6.5 |
| License | MPL-2.0 — full text: [`public/licenses/acadrust-MPL-2.0.txt`](./public/licenses/acadrust-MPL-2.0.txt) (`/licenses/acadrust-MPL-2.0.txt`) |
| Upstream | https://github.com/hakanaktt/acadrust · https://crates.io/crates/acadrust/0.4.1 |
| Upstream commit | `f249c2f816acf36ee51cd5533716bdd443c2517e` (from the crate's `.cargo_vcs_info.json`) |
| Upstream | https://github.com/hakanaktt/acadrust · https://crates.io/crates/acadrust/0.6.5 |
| Upstream commit | `289a616da6c68518218594aa80802cbe7fa71309` (from the crate's `.cargo_vcs_info.json`) |
| Crate SHA-256 | `5eaa72520f70eb6f7f09b06f44e1ed0d8fad5fa743364f2c3715c30df962ec7c` (the `Cargo.lock` checksum the build used) |
| Author | Hakan AK |
| Shipped as | compiled into `assets/acadrust_dwg_bg-*.wasm` (Executable Form) |
**This copy is modified.** One file differs from the published crate:
```
src/io/dwg/dwg_stream_readers/object_reader/entities.rs (read_mesh array-count bounds)
```
The modification bounds `read_mesh`'s array counts by the bits remaining in the
object stream instead of the blanket 100 000-item guard, which truncated and
thereby corrupted large SubD meshes.
**This copy is not modified.** The `.wasm` is built from the published crate
exactly as crates.io serves it.
### How to obtain the Source Code Form (MPL-2.0 §3.2)
1. Get the unmodified crate source — `cargo vendor`, or
`https://crates.io/api/v1/crates/acadrust/0.4.1/download`, or the upstream
commit above.
2. Apply [`public/licenses/acadrust-0.4.1-read_mesh.patch`](./public/licenses/acadrust-0.4.1-read_mesh.patch)
(`/licenses/acadrust-0.4.1-read_mesh.patch` on the deployed site):
Download the crate, which is the complete source compiled into the shipped
`.wasm`:
```bash
tar xf acadrust-0.4.1.crate && cd acadrust-0.4.1
patch -p1 < acadrust-0.4.1-read_mesh.patch
```
```bash
curl -L -o acadrust-0.6.5.crate https://static.crates.io/crates/acadrust/acadrust-0.6.5.crate
tar xzf acadrust-0.6.5.crate
```
The result is the exact Source Code Form of the acadrust code compiled into the
shipped `.wasm`. Both the original and the modified file remain under MPL-2.0.
or `cargo vendor` in any project that depends on `acadrust = "=0.6.5"`, or the
upstream commit above.
---
@@ -1,111 +0,0 @@
--- a/src/io/dwg/dwg_stream_readers/object_reader/entities.rs
+++ b/src/io/dwg/dwg_stream_readers/object_reader/entities.rs
@@ -1682,20 +1682,49 @@
MLineData { scale_factor, justification, start_point, normal, openclosed, lines_in_style, vertex_count, vertices, style_handle }
}
+/// Cap an array count against the bits actually left in the object's main
+/// stream instead of the blanket [`MAX_ARRAY_COUNT`].
+///
+/// MESH is the one entity whose arrays legitimately run past 100 000 items: a
+/// road-surface mesh in a civil drawing carries hundreds of thousands of
+/// vertices. Clamping those to the blanket cap does not merely truncate the
+/// mesh — the reader then continues from the wrong bit offset, so the face,
+/// edge and crease lists that follow decode as garbage (observed: a 100 000
+/// vertex clamp left a 14-face mesh with face sizes `[64, 0, 64, 23, 0, …]`).
+/// Bounding by the remaining bits keeps the corrupt-data protection — no
+/// unbounded allocation is possible — without mis-parsing a valid drawing.
+///
+/// `min_bits_per_item` is the shortest legal encoding of one element: a
+/// BitDouble is 2 bits at minimum (the 0.0 / 1.0 forms), so a 3BD vertex is 6
+/// and a BitLong is 2.
+fn stream_bounded_count(reader: &DwgMergedReader, raw: i32, min_bits_per_item: i64) -> i32 {
+ let raw = raw.max(0) as i64;
+ let total_bits = (reader.main().data_len() as i64).saturating_mul(8);
+ // The handle stream follows the main stream; anything past its start is not
+ // array data. handle_start() is 0 when the framing did not supply it.
+ let handle_start = reader.handle_start();
+ let end_bits = if handle_start > 0 { handle_start.min(total_bits) } else { total_bits };
+ let remaining = (end_bits - reader.position_in_bits()).max(0);
+ raw.min(remaining / min_bits_per_item.max(1)).min(i32::MAX as i64) as i32
+}
+
pub fn read_mesh(reader: &mut DwgMergedReader) -> MeshData {
let version = reader.read_bit_short();
let blend_crease = reader.read_bit();
let subdivision_level = reader.read_bit_long();
- let num_verts = safe_count(reader.read_bit_long());
+ let raw_verts = reader.read_bit_long();
+ let num_verts = stream_bounded_count(reader, raw_verts, 6);
let mut vertices = Vec::with_capacity(num_verts as usize);
for _ in 0..num_verts { vertices.push(reader.read_3bit_double()); }
- let total_face_data = safe_count(reader.read_bit_long());
+ let raw_face_data = reader.read_bit_long();
+ let total_face_data = stream_bounded_count(reader, raw_face_data, 2);
let mut faces = Vec::new();
let mut i = 0;
while i < total_face_data {
- let n = safe_count(reader.read_bit_long());
+ let raw_n = reader.read_bit_long();
+ let n = stream_bounded_count(reader, raw_n, 2);
i += 1;
let mut face = Vec::new();
for _ in 0..n {
@@ -1705,7 +1734,8 @@
faces.push(face);
}
- let num_edges = safe_count(reader.read_bit_long());
+ let raw_edges = reader.read_bit_long();
+ let num_edges = stream_bounded_count(reader, raw_edges, 4);
let mut edges = Vec::with_capacity(num_edges as usize);
for _ in 0..num_edges {
let s = reader.read_bit_long();
@@ -1713,7 +1743,8 @@
edges.push((s, e));
}
- let num_creases = safe_count(reader.read_bit_long());
+ let raw_creases = reader.read_bit_long();
+ let num_creases = stream_bounded_count(reader, raw_creases, 2);
let mut crease_values = Vec::with_capacity(num_creases as usize);
for _ in 0..num_creases { crease_values.push(reader.read_bit_double()); }
@@ -2350,14 +2381,31 @@
pub fn read_ole2frame(reader: &mut DwgMergedReader, version: DwgVersion) -> Ole2FrameData {
let ver = reader.read_bit_short();
let mode = if version.r2000_plus() { reader.read_bit_short() } else { 0 };
- // OLE binary data can be very large (embedded images/documents),
- // so don't use safe_count (100 KB cap). Use a generous 10 MB cap instead.
let data_len = (reader.read_bit_long().max(0) as usize).min(10_000_000);
let data = reader.read_bytes(data_len);
let trailing_byte = if version.r2000_plus() { reader.read_byte() } else { 3 };
- let upper_left = reader.read_3bit_double();
- let lower_right = reader.read_3bit_double();
+
+ let mut upper_left = Vector3::new(0.0, 0.0, 0.0);
+ let mut lower_right = Vector3::new(0.0, 0.0, 0.0);
+
+ // Extract 4-corner coordinates stored in the OLE binary data header starting at offset 2
+ if data.len() >= 66 {
+ let ul_x = f64::from_le_bytes(data[2..10].try_into().unwrap());
+ let ul_y = f64::from_le_bytes(data[10..18].try_into().unwrap());
+ let ul_z = f64::from_le_bytes(data[18..26].try_into().unwrap());
+ let lr_x = f64::from_le_bytes(data[50..58].try_into().unwrap());
+ let lr_y = f64::from_le_bytes(data[58..66].try_into().unwrap());
+ let lr_z = if data.len() >= 74 { f64::from_le_bytes(data[66..74].try_into().unwrap()) } else { 0.0 };
+
+ if ul_x.is_finite() && ul_y.is_finite() && lr_x.is_finite() && lr_y.is_finite()
+ && (ul_x != 0.0 || ul_y != 0.0 || lr_x != 0.0 || lr_y != 0.0) {
+ upper_left = Vector3::new(ul_x, ul_y, if ul_z.is_finite() { ul_z } else { 0.0 });
+ lower_right = Vector3::new(lr_x, lr_y, if lr_z.is_finite() { lr_z } else { 0.0 });
+ }
+ }
+
let ole_type = if version.r2000_plus() { reader.read_byte() } else { 2 };
+
Ole2FrameData { version: ver, mode, data, trailing_byte, upper_left, lower_right, ole_type }
}
Binary file not shown.
Binary file not shown.
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env node
/**
* Parse a DWG in Node — no browser, no Viewer2D. Same acadrust wasm and
* Korean-text fixup as src/viewer2d/dwgParser.ts.
*
* Usage:
* node scripts/parse-dwg.mjs <file.dwg> # print summary
* node scripts/parse-dwg.mjs <file.dwg> out.json # also write full parseResult
*
* Needs Node >= 22.18 (imports fixDwgKoreanText.ts via built-in type stripping).
*/
import { readFileSync, writeFileSync } from 'node:fs';
import { initSync, parse_dwg_json } from '../src/viewer2d/acadrust-dwg/acadrust_dwg.js';
import { fixDwgKoreanText } from '../src/viewer2d/fixDwgKoreanText.ts';
const [inPath, outPath] = process.argv.slice(2);
if (!inPath) {
console.error('usage: node scripts/parse-dwg.mjs <file.dwg> [out.json]');
process.exit(1);
}
const wasmUrl = new URL('../src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm', import.meta.url);
initSync({ module: readFileSync(wasmUrl) });
const t0 = performance.now();
const result = fixDwgKoreanText(JSON.parse(parse_dwg_json(readFileSync(inPath))));
const ms = performance.now() - t0;
const entities = result.entities ?? [];
const byType = {};
for (const e of entities) byType[e.type] = (byType[e.type] ?? 0) + 1;
console.log(`file : ${inPath}`);
console.log(`version : ${result.version}`);
console.log(`parse : ${ms.toFixed(0)} ms`);
console.log(`entities : ${entities.length}`);
console.table(Object.entries(byType).sort((a, b) => b[1] - a[1]).map(([type, count]) => ({ type, count })));
console.log(`tables : ${Object.keys(result.tables ?? {}).join(', ')}`);
if (result.stats) console.log('stats :', result.stats);
if (outPath) {
writeFileSync(outPath, JSON.stringify(result, null, 2));
console.log(`wrote : ${outPath}`);
}
+36
View File
@@ -231,6 +231,7 @@ document.getElementById('theme')!.addEventListener('click', () => {
viewer.setTheme(dark);
fillLayers();
});
// ── 옵션 패널 ────────────────────────────────────────────────────
// 값은 IndexedDB(hmw-viewer/options)에 남는다. 선가중치 배율은 재파싱 없이
// 즉시 반영되므로 드래그하면서 화면을 보고 맞출 수 있다.
@@ -242,6 +243,10 @@ const optLwOut = document.getElementById('optLwOut')!;
const optGrid = document.getElementById('optGrid') as HTMLInputElement;
const optZoomSpeed = document.getElementById('optZoomSpeed') as HTMLInputElement;
const optZoomSpeedNum = document.getElementById('optZoomSpeedNum') as HTMLInputElement;
const opt25D = document.getElementById('opt25D') as HTMLInputElement;
const optZRow = document.getElementById('optZRow')!;
const optZScale = document.getElementById('optZScale') as HTMLInputElement;
const optZScaleNum = document.getElementById('optZScaleNum') as HTMLInputElement;
makePanelDraggableAndCollapsible(optionsPanel, {
collapseBtnEl: document.getElementById('collapseOptBtn')!,
@@ -295,11 +300,41 @@ function applyZoomSpeed(v: number, persist = true) {
optZoomSpeed.addEventListener('input', () => applyZoomSpeed(parseFloat(optZoomSpeed.value)));
optZoomSpeedNum.addEventListener('input', () => applyZoomSpeed(parseFloat(optZoomSpeedNum.value)));
// ── 2.5D 보기 토글 ───────────────────────────────────────────────
// Top 뷰를 풀고 남동 등각(SE Isometric)으로 기울인다. 도면 정점은 이미 CAD
// 표고(Z)를 갖고 있으므로 재파싱·재생성 없이 카메라만 돌리면 등고선 같은
// 높낮이가 그대로 드러난다. 다시 누르면 원래 Top 뷰(회전 잠금)로 돌아온다.
// 뷰 상태라 IndexedDB 에 저장하지 않는다 — Z 과장 배율만 저장한다.
const view25Btn = document.getElementById('view25Btn')!;
function apply25D(on: boolean) {
viewer.set25D(on);
view25Btn.classList.toggle('on', on);
view25Btn.textContent = on ? '2.5D 보기 ✓' : '2.5D 보기';
opt25D.checked = on;
optZRow.classList.toggle('disabled', !on);
setStatus(on ? '2.5D 보기 · 왼쪽 드래그=회전, 가운데·오른쪽 드래그=이동' : 'Top 뷰');
}
view25Btn.addEventListener('click', () => apply25D(!viewer.is25D()));
opt25D.addEventListener('change', () => apply25D(opt25D.checked));
function applyZScale(v: number, persist = true) {
if (!Number.isFinite(v) || v <= 0) return;
viewer.setZScale(v);
optZScale.value = String(v);
optZScaleNum.value = String(v);
if (persist) void setOption('zScale', v);
}
optZScale.addEventListener('input', () => applyZScale(parseFloat(optZScale.value)));
optZScaleNum.addEventListener('input', () => applyZScale(parseFloat(optZScaleNum.value)));
document.getElementById('optReset')!.addEventListener('click', () => {
viewer.setLineweightScale(null); // 뷰어 기본 배율
viewer.setLineweightEnabled(null); // 도면의 LWDISPLAY 를 다시 따름
viewer.setGrid(false);
applyZoomSpeed(1);
applyZScale(1);
apply25D(false);
optGrid.checked = false;
void setOption('lineweightScale', null);
void setOption('lineweightOn', null);
@@ -313,6 +348,7 @@ void getAllOptions().then((o) => {
if (typeof o.lineweightOn === 'boolean') viewer.setLineweightEnabled(o.lineweightOn);
if (o.grid === true) { viewer.setGrid(true); optGrid.checked = true; }
if (typeof o.zoomSpeed === 'number') applyZoomSpeed(o.zoomSpeed, false);
if (typeof o.zScale === 'number') applyZScale(o.zScale, false);
syncOptions();
});
syncOptions();
+163
View File
@@ -0,0 +1,163 @@
/**
* Top loading bar (NProgress-style) for the DWG/DXF load pipeline.
*
* Why two layers:
* The expensive stages — `parse_dwg_json` on the WASM heap and
* `Viewer2D.load()` — are SYNCHRONOUS. While they run, the main thread is
* blocked: no rAF ticks, no `width` transitions, no repaint. A JS-driven bar
* simply freezes for the seconds that matter most.
*
* · `.bar` real progress, driven by `width` (accurate, main-thread bound).
* · `.sweep` liveness, a `transform` keyframe animation. Transform keyframes
* are handed to the compositor thread, so the stripe keeps moving
* across a blocked main thread. That is the only feedback the page
* can give while the parser is inside WASM.
*
* The markup and CSS live in index.html (`#progress`), same as the other
* panels; this module just drives them.
*/
/** Wait until the browser has actually painted the pending style change. */
function nextPaint(): Promise<void> {
return new Promise<void>((resolve) => {
let settled = false;
const finish = () => {
if (settled) return;
settled = true;
resolve();
};
// Two frames: the first callback still runs BEFORE paint, the second one
// only fires once the frame carrying our change has been composited.
requestAnimationFrame(() => requestAnimationFrame(finish));
// Backgrounded tabs never fire rAF — don't stall the load behind it.
setTimeout(finish, 150);
});
}
export class TopProgress {
private root: HTMLElement;
private bar: HTMLElement;
private value = 0;
private hideTimer = 0;
constructor(root: HTMLElement) {
this.root = root;
this.bar = root.querySelector<HTMLElement>('.bar') ?? root;
}
/** Show the bar and reset it to zero (no rewind animation). */
start(): void {
window.clearTimeout(this.hideTimer);
this.root.classList.remove('err');
this.value = 0;
this.jumpTo(0);
this.root.classList.add('on');
}
/**
* Move to `v` (0–1). Monotonic — a lower value is ignored, so out-of-order
* stage callbacks can never make the bar walk backwards.
*/
set(v: number): void {
const next = Math.max(this.value, Math.min(1, Math.max(0, v)));
if (next === this.value) return;
this.value = next;
this.bar.style.width = `${(next * 100).toFixed(2)}%`;
}
/** Toggle the compositor-driven sweep for a stage that blocks the main thread. */
busy(on: boolean): void {
this.root.classList.toggle('busy', on);
}
/** Resolve once the pending width/class change is on screen. */
paint(): Promise<void> {
return nextPaint();
}
/** Fill to 100% and fade out. */
done(): void {
this.finish();
}
/** Fill to 100% in the error color and fade out. */
fail(): void {
this.root.classList.add('err');
this.finish();
}
private finish(): void {
this.busy(false);
this.set(1);
window.clearTimeout(this.hideTimer);
this.hideTimer = window.setTimeout(() => {
this.root.classList.remove('on');
// Rewind only after the fade-out has finished, so the bar never visibly
// slides back to zero.
this.hideTimer = window.setTimeout(() => {
this.root.classList.remove('err');
this.value = 0;
this.jumpTo(0);
}, 320);
}, 260);
}
/** Set the width with the transition suppressed for one frame. */
private jumpTo(v: number): void {
const prev = this.bar.style.transition;
this.bar.style.transition = 'none';
this.bar.style.width = `${(v * 100).toFixed(2)}%`;
void this.bar.offsetWidth; // force reflow so the next change animates again
this.bar.style.transition = prev;
}
}
/** 1.4 MB / 812 kB — short byte label for the download readout. */
export function formatBytes(n: number): string {
if (!Number.isFinite(n) || n < 0) return '?';
if (n < 1024) return `${n} B`;
if (n < 1024 * 1024) return `${(n / 1024).toFixed(0)} kB`;
return `${(n / 1024 / 1024).toFixed(1)} MB`;
}
/**
* fetch() that reports download progress.
*
* Falls back to a plain `arrayBuffer()` when the response has no body stream
* or no Content-Length (then `total` is 0 and the caller should show an
* indeterminate state). `loaded` is decompressed bytes while Content-Length is
* the compressed size, so the ratio is clamped to 1.
*/
export async function fetchWithProgress(
url: string,
onProgress: (loaded: number, total: number) => void,
): Promise<ArrayBuffer> {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const total = Number(res.headers.get('content-length')) || 0;
if (!res.body || !total) {
const buf = await res.arrayBuffer();
onProgress(buf.byteLength, buf.byteLength);
return buf;
}
const reader = res.body.getReader();
const chunks: Uint8Array[] = [];
let loaded = 0;
for (;;) {
const { done, value } = await reader.read();
if (done) break;
if (!value) continue;
chunks.push(value);
loaded += value.length;
onProgress(loaded, total);
}
const out = new Uint8Array(loaded);
let offset = 0;
for (const c of chunks) {
out.set(c, offset);
offset += c.length;
}
return out.buffer;
}
+6
View File
@@ -18,6 +18,12 @@ export class Viewer2D {
setGrid(visible: boolean): void;
setZoomSpeed(speed: number): void;
getZoomSpeed(): number;
/** 2.5D (tilted 3D) view: orbit the drawing so entity elevation (Z) is visible. */
set25D(on: boolean, opts?: { keepView?: boolean }): void;
is25D(): boolean;
/** Height exaggeration for 2.5D (1 = true scale); ignored in top view. */
setZScale(k: number): void;
getZScale(): number;
/** Lineweight display (AutoCAD LWDISPLAY); null follows the drawing's own flag. */
setLineweightEnabled(on: boolean | null): void;
getLineweightEnabled(): boolean;
+248 -4
View File
@@ -108,6 +108,22 @@ export class Viewer2D {
this._lwDisplay = false;
this._curLwPx = 0;
this._lwScale = null; // null = LW_PX_PER_MM (setLineweightScale)
// ── 2.5D view ────────────────────────────────────────────────────────────
// Entities already carry their CAD elevation (Z) in the vertex buffers —
// the classic view simply stares straight down at them. 2.5D re-aims the
// same orthographic camera at an isometric angle and unlocks OrbitControls'
// rotate, so contours / TIN / 3D polylines show their relief. Nothing is
// re-tessellated: toggling is a camera + controls change only.
this._is25D = false;
this._zScale = 1; // height exaggeration (flat relief over a wide site)
this._need25Reset = false; // next _fit should snap back to the default angle
this._contentZ = null; // true Z range of the load (the fit box is flattened)
// Active viewport transform for filled geometry, set only while
// _emitModelThroughViewport runs. Lines reach the viewport through pushSeg,
// but SOLID/HATCH fills and dimension arrowheads hand a finished mesh built
// from model coordinates straight to _addObj — this is how that mesh finds
// out it belongs on a sheet. null outside the viewport pass.
this._fillXf = null;
SlugTextEngine.shared().catch(() => {}); // warm the font load; sprite fallback covers failure
this._scene = new THREE.Scene();
@@ -180,6 +196,104 @@ export class Viewer2D {
setZoomSpeed(speed) { if (this._controls) this._controls.zoomSpeed = speed; }
getZoomSpeed() { return this._controls ? this._controls.zoomSpeed : 1.0; }
// ── 2.5D view ──────────────────────────────────────────────────────────────
/**
* Toggle the 2.5D (tilted 3D) view.
*
* ON — camera moves to an SE-isometric angle (+X/−Y/+Z, the AutoCAD default),
* Z becomes the orbit pole and LEFT-drag orbits (MIDDLE/RIGHT still pan).
* OFF — straight-down top view with rotate locked; identical to before.
*
* Geometry is untouched, so layer masks, lineweights and picking survive.
* @param {boolean} on
* @param {{ keepView?: boolean }} [opts] keepView skips the zoom-extents re-fit
*/
set25D(on, opts = {}) {
const want = !!on;
if (want === this._is25D) return;
this._is25D = want;
this._need25Reset = want;
const c = this._controls;
if (want) {
c.enableRotate = true;
c.mouseButtons = { LEFT: THREE.MOUSE.ROTATE, MIDDLE: THREE.MOUSE.PAN, RIGHT: THREE.MOUSE.PAN };
c.touches = { ONE: THREE.TOUCH.ROTATE, TWO: THREE.TOUCH.DOLLY_PAN };
// CAD elevation is +Z, so the orbit pole must be Z or dragging feels sideways.
this._camera.up.set(0, 0, 1);
} else {
c.enableRotate = false;
c.mouseButtons = { LEFT: THREE.MOUSE.PAN, MIDDLE: THREE.MOUSE.PAN, RIGHT: THREE.MOUSE.PAN };
c.touches = { ONE: THREE.TOUCH.PAN, TWO: THREE.TOUCH.DOLLY_PAN };
}
this._applyZScale();
if (opts.keepView) { c.update(); return; }
this.fit();
}
is25D() { return this._is25D; }
/**
* Height exaggeration for 2.5D. A survey sheet is often kilometres wide with
* only metres of relief, which reads as dead flat at any orbit angle —
* multiplying Z makes the terrain legible. Only applied in 2.5D (in top view
* it would be invisible anyway) and only as a scale on the scene group, so
* pick coordinates and the X/Y readout stay true to the drawing.
* @param {number} k >0; 1 = true scale
*/
setZScale(k) {
const v = Number(k);
this._zScale = Number.isFinite(v) && v > 0 ? v : 1;
this._applyZScale();
this._refreshClip25();
}
getZScale() { return this._zScale; }
_applyZScale() {
this._group.scale.set(1, 1, this._is25D ? (this._zScale || 1) : 1);
this._group.updateMatrixWorld(true);
}
/** True Z extents of the drawing (the fit box is flattened to z=0). */
_zRange() {
const z = this._contentZ;
if (!z || !Number.isFinite(z.min) || !Number.isFinite(z.max)) return { min: 0, max: 0 };
return z;
}
/**
* Re-cut the orthographic clip slab around the (possibly Z-exaggerated)
* content without moving the camera — otherwise a big exaggeration pushes
* geometry through `near`/`far` and it vanishes mid-drag.
*/
_refreshClip25() {
if (!this._is25D) return;
const box = this._box25(this._contentBox || this._fullContentBox);
if (!box) return;
const diag = Math.max(box.getSize(new THREE.Vector3()).length(), 1e-6);
const span = this._camera.position.distanceTo(this._controls.target) + diag + 1;
this._camera.near = -span;
this._camera.far = span;
this._camera.updateProjectionMatrix();
}
/** Fit box with the real (exaggerated) Z range restored. */
_box25(src) {
if (!src || src.isEmpty()) return null;
const b = src.clone();
if (b.max.z - b.min.z < 1e-9) {
const z = this._zRange();
b.min.z = z.min;
b.max.z = z.max;
}
const k = this._zScale || 1;
b.min.z *= k;
b.max.z *= k;
if (b.max.z < b.min.z) { const t = b.min.z; b.min.z = b.max.z; b.max.z = t; }
return b;
}
/**
* Subscribe to mouse world-coordinate updates (CAD WCS / drawing units).
* Callback receives `{ x, y, z }` or `null` when the pointer leaves the canvas.
@@ -213,6 +327,19 @@ export class Viewer2D {
const ndcX = ((clientX - rect.left) / rect.width) * 2 - 1;
const ndcY = -((clientY - rect.top) / rect.height) * 2 + 1;
// 2.5D: the view no longer lies in the drawing plane, so shoot the (parallel)
// ortho ray through the pixel and intersect the Z=0 plane. Exact for the
// drawing plane itself; entities lifted by their elevation read as the point
// of the plane under them, which is what a plan-coordinate readout means.
if (this._is25D) {
// Cached vectors: this runs on every pointermove.
const o = (this._ray25O ||= new THREE.Vector3()).set(ndcX, ndcY, -1).unproject(cam);
const d = cam.getWorldDirection(this._ray25D ||= new THREE.Vector3());
if (Math.abs(d.z) < 1e-9) return null;
const t = -o.z / d.z;
return { x: o.x + d.x * t, y: o.y + d.y * t, z: 0 };
}
// Orthographic frustum half-sizes in world units (respect zoom).
const zoom = cam.zoom || 1;
const halfW = ((cam.right - cam.left) * 0.5) / zoom;
@@ -531,6 +658,7 @@ export class Viewer2D {
setCurLayer,
box,
_tmp,
fillZ: VIEWPORT_Z, // fills ride the same underlay plane as the wires
underlay: true, // tag pending texts drawn under paper labels
});
}
@@ -1237,6 +1365,9 @@ export class Viewer2D {
const fitBox = box.isEmpty() ? null : (this._trimmedContentBox(fitSamples, box) || box);
this._fullContentBox = fitBox ? fitBox.clone() : null;
this._contentBox = fitBox ? fitBox.clone() : null;
// The trimmed fit box is flattened to z=0 (percentile trim is X/Y only), so
// keep the drawing's real elevation range for the 2.5D fit.
this._contentZ = box.isEmpty() ? null : { min: box.min.z, max: box.max.z };
// Geometry for every layer is in the scene now — switch off the hidden ones
// (also refreshes _contentBox to the visible subset).
this._applyLayerVisibility();
@@ -1274,8 +1405,10 @@ export class Viewer2D {
_rebuildGrid() {
if (this._gridMesh) { this._scene.remove(this._gridMesh); this._gridMesh.geometry.dispose(); this._gridMesh.material.dispose(); this._gridMesh = null; }
const zoom = this._camera.zoom || 1;
const cx = this._camera.position.x;
const cy = this._camera.position.y;
// Centre on the orbit target, not the camera: in 2.5D the camera sits off to
// the side of what it is looking at.
const cx = this._controls?.target?.x ?? this._camera.position.x;
const cy = this._controls?.target?.y ?? this._camera.position.y;
const hw = (this._camera.right - this._camera.left) / zoom / 2;
const hh = (this._camera.top - this._camera.bottom) / zoom / 2;
const ext = Math.max(hw, hh) * 3;
@@ -1414,6 +1547,14 @@ export class Viewer2D {
/** Track an entity-owned object so layer toggles can flip its visibility. */
_addObj(obj, layer) {
// Inside a paper-space VIEWPORT this mesh is still in model coordinates.
// Drop it when it maps outside the viewport frame, exactly as _clipSegToRect
// drops line work.
if (this._fillXf && !this._bakeFillXf(obj)) {
obj.geometry?.dispose();
if (obj.material) { obj.material.map?.dispose(); obj.material.dispose(); }
return;
}
const key = layer ?? this._curLayer;
if (key != null) {
obj.userData.cadLayer = key;
@@ -1656,6 +1797,53 @@ export class Viewer2D {
}
}
/**
* Bake the active viewport transform into a filled mesh and report whether it
* survives the viewport frame.
*
* _solidMesh / _hatchFill / _arrowMesh / _dotMesh build their own THREE.Mesh
* and never touch pushSeg, so the model→paper mapping has to happen here or
* not at all. Left unmapped they sit at raw survey coordinates: off the sheet,
* and dragging the content box out to the drawing's WCS origin — a sheet 18
* units wide framed inside a 480,000-unit box renders as a blank screen.
*
* The mesh's own transform is folded in first (arrowheads carry their position
* and rotation on the object, not in the buffer), then reset, so the paper
* coordinates end up in the geometry where the fit box can see them.
* @returns {boolean} false when the mesh lies wholly outside the viewport.
*/
_bakeFillXf(obj) {
const { xf, clip, z } = this._fillXf;
const pos = obj.geometry?.attributes?.position;
if (!pos?.array) return true;
obj.updateMatrix();
const m = obj.matrix;
const v = (this._fillTmp ||= new THREE.Vector3());
const arr = pos.array;
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
for (let i = 0; i + 2 < arr.length; i += 3) {
v.set(arr[i], arr[i + 1], arr[i + 2]).applyMatrix4(m);
const p = xf(v.x, v.y);
arr[i] = p.x;
arr[i + 1] = p.y;
// Viewport content sits behind paper entities (see VIEWPORT_Z), but keep
// the helpers' own bias — arrowheads are lifted 0.5 above the dimension
// line they cap — scaled down so it can't cross into the paper layer.
arr[i + 2] = z + (v.z || 0) * 1e-3;
if (p.x < minX) minX = p.x;
if (p.x > maxX) maxX = p.x;
if (p.y < minY) minY = p.y;
if (p.y > maxY) maxY = p.y;
}
pos.needsUpdate = true;
obj.position.set(0, 0, 0);
obj.rotation.set(0, 0, 0);
obj.scale.set(1, 1, 1);
obj.updateMatrix();
obj.geometry.computeBoundingSphere();
return !(maxX < clip.minX || minX > clip.maxX || maxY < clip.minY || minY > clip.maxY);
}
/**
* Emit model-space geometry into a paper VIEWPORT (transformed + clipped).
* Covers the entity types that dominate civil plan/profile sheets.
@@ -1686,6 +1874,11 @@ export class Viewer2D {
};
const inClip = (x, y) => x >= clip.minX && x <= clip.maxX && y >= clip.minY && y <= clip.maxY;
// Hand the mapping to _addObj for the fills that bypass pushSeg. Cleared at
// the end of the pass (and in _clear) so paper-space entities, which are
// already in sheet coordinates, are never re-mapped.
this._fillXf = { xf, clip, z: ctx.fillZ ?? 0 };
// Quick reject: model bbox far from view focus (optional optimisation skip for correctness)
for (const e of entities) {
@@ -1914,6 +2107,8 @@ export class Viewer2D {
}
}
this._fillXf = null;
// Transform any pending texts that are still in model space (from INSERT helpers).
// Entries created above already have paper pos. Detect model-space leftovers by
// checking if pos lies far outside the paper clip *and* inside a model-ish range —
@@ -4174,9 +4369,13 @@ export class Viewer2D {
// Pad slightly so content is not flush to the view edge
const padX = Math.max((maxX - minX) * 0.02, 1);
const padY = Math.max((maxY - minY) * 0.02, 1);
// Trimming is X/Y only — carry the full box's Z through. Pinning Z to 0 here
// and then clamping to fullBox below collapsed the box to empty whenever the
// drawing sat entirely off the z=0 plane, which is exactly where viewport
// underlay geometry lives (VIEWPORT_Z), and an empty box makes _fit a no-op.
const box = new THREE.Box3(
new THREE.Vector3(minX - padX, minY - padY, 0),
new THREE.Vector3(maxX + padX, maxY + padY, 0),
new THREE.Vector3(minX - padX, minY - padY, fullBox.min.z),
new THREE.Vector3(maxX + padX, maxY + padY, fullBox.max.z),
);
// Never expand beyond the true full box
box.min.max(fullBox.min);
@@ -4195,6 +4394,7 @@ export class Viewer2D {
*/
_fit(box) {
if (!box || box.isEmpty()) return;
if (this._is25D) { this._fit25(box); return; }
const c = box.getCenter(new THREE.Vector3());
const size = box.getSize(new THREE.Vector3());
const w = this._container.clientWidth || 800;
@@ -4240,6 +4440,48 @@ export class Viewer2D {
this._controls.update();
}
/**
* Zoom-extents for the tilted view. The box is sized by its 3D diagonal so the
* drawing stays framed at *any* orbit angle — re-fitting on every rotation
* would fight the user's drag.
*/
_fit25(box) {
const b = this._box25(box);
if (!b) return;
const c = b.getCenter(new THREE.Vector3());
const diag = Math.max(b.getSize(new THREE.Vector3()).length(), 1e-6);
const w = this._container.clientWidth || 800;
const h = this._container.clientHeight || 600;
const aspect = w / Math.max(h, 1);
const need = diag * 1.1;
const vw = aspect >= 1 ? need * aspect : need;
const vh = aspect >= 1 ? need : need / aspect;
// Entering 2.5D snaps to SE isometric (+X/−Y/+Z, AutoCAD's default view);
// a later Fit keeps whatever angle the user orbited to.
const dir = new THREE.Vector3();
if (this._need25Reset) dir.set(1, -1, 1);
else dir.subVectors(this._camera.position, this._controls.target);
if (dir.lengthSq() < 1e-12) dir.set(1, -1, 1);
dir.normalize();
this._need25Reset = false;
const dist = diag * 2 + 1; // ortho: only anchors the clip slab, not the scale
this._camera.zoom = 1;
this._camera.left = -vw / 2; this._camera.right = vw / 2;
this._camera.top = vh / 2; this._camera.bottom = -vh / 2;
const span = dist + diag + 1;
this._camera.near = -span;
this._camera.far = span;
this._camera.up.set(0, 0, 1);
this._controls.target.copy(c);
this._camera.position.copy(c).addScaledVector(dir, dist);
this._camera.lookAt(this._controls.target);
this._camera.updateProjectionMatrix();
this._camera.updateMatrixWorld(true);
this._controls.update();
}
_clear() {
for (let i = this._group.children.length - 1; i >= 0; i--) {
const o = this._group.children[i];
@@ -4253,6 +4495,7 @@ export class Viewer2D {
this._textGen++; // invalidate any in-flight async text flush
this._contentBox = null;
this._fullContentBox = null;
this._contentZ = null;
this._layerObjs.clear();
this._layerBoxes.clear();
this._layerSamples.clear();
@@ -4263,6 +4506,7 @@ export class Viewer2D {
this._curLayer = null;
this._curLayerId = -1;
this._layerInfoCache = null;
this._fillXf = null; // a load that threw mid-viewport must not leak its transform
}
_onResize() {
+1
View File
@@ -24,6 +24,7 @@ export interface InitOutput {
readonly parse_dwg_json: (a: number, b: number) => [number, number, number, number];
readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __externref_table_alloc: () => number;
readonly __wbindgen_externrefs: WebAssembly.Table;
readonly __externref_table_dealloc: (a: number) => void;
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
+38
View File
@@ -65,6 +65,10 @@ function __wbg_get_imports() {
const ret = typeof(arg0) === 'string';
return ret;
},
__wbg___wbindgen_is_undefined_c05833b95a3cf397: function(arg0) {
const ret = arg0 === undefined;
return ret;
},
__wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
},
@@ -80,6 +84,14 @@ function __wbg_get_imports() {
const ret = new Object();
return ret;
},
__wbg_now_e7c6795a7f81e10f: function(arg0) {
const ret = arg0.now();
return ret;
},
__wbg_performance_3fcf6e32a7e1ed0a: function(arg0) {
const ret = arg0.performance;
return ret;
},
__wbg_set_575dd786d51585f8: function(arg0, arg1, arg2) {
const ret = arg0.set(arg1, arg2);
return ret;
@@ -90,6 +102,22 @@ function __wbg_get_imports() {
__wbg_set_8a16b38e4805b298: function(arg0, arg1, arg2) {
arg0[arg1 >>> 0] = arg2;
},
__wbg_static_accessor_GLOBAL_4ef717fb391d88b7: function() {
const ret = typeof global === 'undefined' ? null : global;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
},
__wbg_static_accessor_GLOBAL_THIS_8d1badc68b5a74f4: function() {
const ret = typeof globalThis === 'undefined' ? null : globalThis;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
},
__wbg_static_accessor_SELF_146583524fe1469b: function() {
const ret = typeof self === 'undefined' ? null : self;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
},
__wbg_static_accessor_WINDOW_f2829a2234d7819e: function() {
const ret = typeof window === 'undefined' ? null : window;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
},
__wbindgen_cast_0000000000000001: function(arg0) {
// Cast intrinsic for `F64 -> Externref`.
const ret = arg0;
@@ -126,6 +154,12 @@ function __wbg_get_imports() {
};
}
function addToExternrefTable0(obj) {
const idx = wasm.__externref_table_alloc();
wasm.__wbindgen_externrefs.set(idx, obj);
return idx;
}
let cachedDataViewMemory0 = null;
function getDataViewMemory0() {
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
@@ -146,6 +180,10 @@ function getUint8ArrayMemory0() {
return cachedUint8ArrayMemory0;
}
function isLikeNone(x) {
return x === undefined || x === null;
}
function passArray8ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 1, 1) >>> 0;
getUint8ArrayMemory0().set(arg, ptr / 1);
Binary file not shown.
+1
View File
@@ -5,6 +5,7 @@ export const parse_dwg: (a: number, b: number) => [number, number, number];
export const parse_dwg_json: (a: number, b: number) => [number, number, number, number];
export const __wbindgen_malloc: (a: number, b: number) => number;
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
export const __externref_table_alloc: () => number;
export const __wbindgen_externrefs: WebAssembly.Table;
export const __externref_table_dealloc: (a: number) => void;
export const __wbindgen_free: (a: number, b: number, c: number) => void;
+1 -1
View File
@@ -1,6 +1,6 @@
/**
* DWG parser — rust/dwg-wasm wrapper around the acadrust crate (MPL-2.0,
* vendored with a local read_mesh patch; see hmwebviewer rust/dwg-wasm). Emits
* 0.6.5 from crates.io, unmodified; see hmwebviewer rust/dwg-wasm). Emits
* the parseResult shape Viewer2D.load() consumes. Lazy-imported so the wasm is
* only fetched when a DWG is actually opened.
*