dwg-dxf-viewer-sample

DWG/DXF 2D viewer module과 다중 포맷 3D viewer sample을 함께 관리하는 Three.js 기반 npm workspace입니다.

현재 구현은 파일을 브라우저에서 파싱하고 화면에 표시하는 기술 검증용입니다. 좌표, 단위, 원점, 형상 허용오차, topology와 CAD/BIM 의미 정보의 보존을 보장하는 운영용 engineering viewer로는 아직 검증되지 않았습니다.

검토 기준

항목 내용
기준일 2026-07-29
기준 commit 3279ac099ec30bb52363710c73fbd4fe174b707b
기준 tree 위 commit과 2026-07-29 작업 tree의 미커밋 변경 포함
대상 cyhan/dwg-dxf-viewer-sample
참조 형제 저장소 hmwebviewer/README.md의 분석 구조와 3D asset provenance
검토 범위 workspace 구조, 2D/3D 기능, source·test·build 설정, 입력 경계, npm dependency, WASM·font·decoder·fixture license
기능 판정 내부 개발·기능 검증 조건부 GO
외부 배포 판정 NO-GO — license·source 제공·asset provenance blocker 존재

외부 배포 판정은 기술적인 compliance 준비 상태를 뜻합니다. 법률 자문이 아니며, 실제 계약·특허·상표와 배포 승인은 조직의 법무·오픈소스 정책으로 확정해야 합니다.

Workspace 구성

Workspace 역할 주요 runtime
apps/viewer-2d-sample DWG/DXF sample UI와 입력 정책 @hmwebviewer/viewer2d, Three.js
packages/viewer2d 재사용 가능한 2D parser·renderer module dxf-parser, opentype.js, Three.js peer, acadrust WASM
apps/viewer-3d 다중 포맷 3D static web application Three.js, web-ifc
dwg-dxf-viewer-sample/
├─ apps/
│  ├─ viewer-2d-sample/   # 2D sample application
│  └─ viewer-3d/          # 3D sample application과 offline 도구
├─ packages/
│  └─ viewer2d/           # 2D public module
├─ tests/                 # Vitest와 Playwright
├─ LICENSES/              # 현재 MPL-2.0, OFL-1.1 전문
├─ THIRD_PARTY_NOTICES.md
└─ docs/PROVENANCE.md

세 workspace는 "private": true이며 npm registry 배포용 package가 아닙니다. @hmwebviewer/viewer2d의 export도 현재 TypeScript source를 직접 가리키므로, 독립 배포 package가 아니라 이 workspace 안에서 재사용하는 module입니다.

현재 제공 기능

DWG/DXF 2D viewer

  • .dwg, .dxf URL과 로컬 파일 load
  • 파일 선택, Drag & Drop, ?model=<url> 진입 경로
  • DWG는 acadrust WebAssembly parser, DXF는 dxf-parser와 adapter 사용
  • Three.js orthographic renderer와 pan·zoom
  • Zoom Fit, dark/light theme, layer별 표시·숨김
  • entity click 선택과 type·layer·handle 표시
  • TEXT/MTEXT glyph용 NanumGothic TTF load
  • module API의 grid, zoom speed, view-change 구독, entity/block 통계, WebP snapshot, 2점 거리 측정, accent color
  • page 종료 시 RAF, listener, WebGL resource와 canvas dispose

renderer에는 LINE, CIRCLE, ARC, ELLIPSE, POINT, POLYLINE/LWPOLYLINE, SPLINE, TEXT/MTEXT/ATTRIB, INSERT, HATCH, DIMENSION, LEADER, XLINE/RAY 등 여러 entity 경로가 있습니다. 모든 DWG/DXF version과 entity 조합의 정확도를 보장한다는 의미는 아닙니다.

2D 입력 경계는 application layer에서 다음과 같이 제한합니다.

  • URL은 HTTP(S)와 viewer 동일 origin만 허용
  • Content-Length와 streaming 누적 크기를 모두 확인
  • 로컬·URL 입력 최대 50 MiB
  • URL fetch timeout 15초

다중 포맷 3D viewer

  • ?model=<url> server asset load와 로컬 Drag & Drop
  • GLB, GLTF, OBJ, FBX, DAE, IFC, PLY load
  • OBJ와 함께 드롭한 MTL 및 PNG/JPEG/BMP/GIF/WebP/TGA texture 연결
  • 300 MiB 초과 OBJ의 2-pass streaming parser
  • 큰 절대 좌표를 가진 OBJ의 float64 source 단계 재중심화
  • Draco geometry와 KTX2/Basis texture runtime decode
  • IFC single-thread WebAssembly parse와 geometry 변환
  • PLY mesh·point cloud 처리 및 Float64 attribute의 Float32 정규화
  • OrbitControls, Zoom Fit, 원근·직교 projection, outline 표시
  • FPS overlay와 지속적인 저 FPS에서 pixel ratio를 낮추는 adaptive quality
  • model URL과 이름이 같은 360° WebP preview를 먼저 표시한 뒤 canvas로 전환
  • Vite BASE_URL을 따르는 decoder·preview 경로와 subpath 배포
  • 교체 model의 geometry·material·texture와 Blob URL 정리

WebP preview는 미리 생성된 정적 파일입니다. Vite가 HTML shell을 제공한 뒤 브라우저에서 preview와 model을 load하므로 server-side 3D rendering 또는 SSR 구현은 없습니다.

실행 구조

flowchart TD
    A["2D File / same-origin URL"] --> B["cadInputPolicy"]
    B --> C["parseCad"]
    C --> D["acadrust WASM<br/>DWG"]
    C --> E["dxf-parser + adapter<br/>DXF"]
    D --> F["CadParseResult"]
    E --> F
    F --> G["Viewer2D / Three.js"]

    H["3D File / ?model URL"] --> I["ThreeDViewer"]
    I --> J["modelLoader"]
    J --> K["Three.js format loaders"]
    J --> L["web-ifc JS + WASM"]
    K --> M["THREE.Object3D"]
    L --> M
    M --> N["WebGLRenderer"]

2D application은 packages/viewer2d 내부 파일을 직접 import하지 않고 @hmwebviewer/viewer2d public interface를 사용합니다. 3D modelLoader는 확장자로 loader를 선택하고 결과를 THREE.Object3D로 정규화합니다.

npm ci의 root postinstall은 Three.js의 Draco·Basis 파일과 web-ifc WASM을 apps/viewer-3d/public 아래에 staging합니다. runtime에서는 설치된 Three.js와 동일한 decoder를 사용합니다. web-ifc-mt.wasm도 복사되지만 현재 code path는 single-thread web-ifc.wasm만 사용합니다.

지원 범위와 알려진 제한

2D

포맷 URL 로컬 파일 현재 검증과 제한
DWG 동일 origin 지원 지원 BasicSample.dwg 1개 fixture 중심. acadrust WASM wrapper의 재현 build source가 없음
DXF 동일 origin 지원 지원 simple.dxf와 public parser contract 검증. binary DXF 및 전체 entity fidelity 미검증

3D

포맷 ?model URL 로컬 파일 알려진 제한
GLB 지원 지원 Draco/KTX2 지원. 손실 압축 허용오차와 원본 대비 fidelity 기준 없음
GLTF 지원 제한적 로컬 .bin·texture sidecar를 함께 해석하는 file-set session 없음
OBJ 지원 지원 URL 경로의 MTL 자동 load 없음. 로컬만 MTL·texture sidecar 지원
OBJ > 300 MiB 지원 지원 streaming path는 smooth normal과 MTL Kd color만 사용하고 texture·hard edge fidelity를 포기
FBX 지원 지원 축·단위·animation·외부 texture 보존 계약 없음
DAE 지원 제한적 로컬 외부 texture sidecar 미지원
IFC 지원 지원 geometry와 color만 Three.js object로 변환. property/semantic API와 원점 이동 기록 미보존
PLY 지원 지원 mesh 또는 point cloud. double attribute는 GPU용 Float32로 변환되어 정밀도 손실 가능

여기서 “지원”은 sample을 파싱해 renderable object를 만들 수 있다는 뜻입니다. CAD/BIM 원본과의 좌표·단위·원점·topology·재질·속성 일치를 의미하지 않습니다.

신뢰 경계와 운영 위험

2D 경로는 same-origin, 50 MiB, 15초 제한을 적용하지만 magic bytes, MIME, 압축 해제 후 entity 수와 geometry 복잡도 quota는 없습니다.

3D ?model은 URL scheme·origin·크기·timeout을 제한하지 않습니다. browser CORS가 허용하면 외부 origin도 요청할 수 있고, GLTF/DAE/FBX/OBJ가 참조하는 URI가 추가 network request를 만들 수 있습니다. 로컬 3D 파일에도 최대 크기와 decode 후 vertex·texture·memory quota가 없습니다.

두 viewer 모두 parser와 상당한 geometry 처리를 browser main thread에서 수행합니다. 운영 배포에는 format별 Worker 격리, URL allowlist, CSP, MIME·signature 검사, streaming byte limit, decode complexity quota, timeout과 cancellation이 필요합니다.

동시에 여러 load를 시작했을 때 이전 요청을 취소하거나 latest-wins를 보장하는 session 규약도 없습니다. 느린 이전 요청이 나중 요청 뒤에 완료되어 화면을 덮을 수 있습니다.

현재 E2E는 sample render, finite vertex, canvas lifecycle과 subpath decoder URL을 검사합니다. 공식 validator, golden geometry, 좌표·단위 왕복, topology, material·IFC property contract와 장시간 memory soak는 release gate에 없습니다.

외부 의존성·라이선스 감사

배포 준비 판정: 외부 demo·고객 전달·public CDN·commercial SaaS NO-GO, 조직 내부 개발·검증 조건부 GO

dependency 자체는 대부분 상업 사용 가능한 license이지만, 프로젝트 소유 코드의 license, MPL source 제공, Apache/MIT 고지와 sample provenance가 완결되지 않았습니다.

감사 범위는 package-lock.jsonnode_modules/* entry, 실제 browser bundle, public 정적 파일, bundled WASM·font, sample과 파생 preview, repository가 호출하거나 언급하는 system tool입니다.

lockfile에는 142개 node_modules/* entry가 있습니다. 이 중 3개는 이 저장소의 workspace link이고 제3자 package는 139개입니다. 제3자 entry의 license metadata 누락은 0개입니다. runtime entry는 5개, build/dev entry는 134개이며 그중 57개는 platform별 optional package입니다.

Browser runtime과 직접 배포되는 구성요소

구성요소 버전·출처 역할·배포 위치 License 현재 compliance 상태
Three.js 0.185.1 두 viewer의 JS bundle, loader·controls MIT package license는 확인. 배포 artifact에 통합 MIT notice 없음
dxf-parser 1.1.2 DXF parser JS bundle MIT package license는 확인. 통합 notice 없음
loglevel 1.9.2, dxf-parser transitive DXF runtime logging MIT lockfile·package license 확인
opentype.js 2.0.0 TTF glyph 처리 JS bundle MIT package license는 확인. 통합 notice 없음
acadrust WASM 내부 0.4.1 acadrust_dwg_bg.wasm, DWG parse MPL-2.0 MPL 전문과 checksum은 있음. wrapper source·toolchain과 재현 build가 없음
NanumGothic Google Fonts 원본 checksum 일치 NanumGothic-Regular.ttf OFL-1.1 전문과 checksum은 있음. root license 파일이 app dist에는 자동 포함되지 않음
web-ifc 0.0.77 dynamic JS bundle, /web-ifc/*.wasm MPL-2.0 package 전문은 확인. exact covered source 취득 안내가 배포물에 없음
Draco decoder Three.js r185 배포본 /draco/*.js, /draco/*.wasm Apache-2.0 source와 byte-for-byte staging test 있음. Apache 전문·NOTICE가 app dist에 없음
Basis Universal transcoder Three.js r185 배포본 /basis/*.js, /basis/*.wasm Apache-2.0 basis/README.md에 upstream link만 있음. Apache 전문·NOTICE가 app dist에 없음

저장소의 THIRD_PARTY_NOTICES.md는 acadrust, NanumGothic과 주요 runtime library를 기록하고, LICENSES/에는 MPL-2.0과 OFL-1.1 전문이 있습니다. 그러나 이 파일들은 두 Vite application의 public 아래에 있지 않아 현재 npm run build 결과에는 포함되지 않습니다.

전체 npm license 집계

License 제3자 package entry 수 주 사용 범위 상업 사용 source 공개 영향
MIT 86 runtime 4개와 build/dev 가능 프로젝트 source 공개 의무 없음. copyright·license notice 보존
Apache-2.0 31 TypeScript, Playwright, Puppeteer와 platform package 가능 프로젝트 source 공개 의무 없음. license·변경·NOTICE·patent 조건 적용
MPL-2.0 13 web-ifc runtime 1개, Lightning CSS 계열 dev 12개 가능 외부 executable 배포 시 covered source와 취득 안내 필요
ISC 6 build/dev 가능 copyright·permission notice 보존
BSD-3-Clause 2 build/dev 가능 notice·면책 보존, 이름을 홍보에 사용하지 않음
0BSD 1 optional build/dev 가능 source 공개와 attribution 의무 없음

위 집계에는 npm 밖의 acadrust WASM, NanumGothic, Draco, Basis와 sample asset license가 포함되지 않습니다. UNKNOWN 3개처럼 보이는 lockfile entry는 @hmwebviewer/* first-party workspace link이며 제3자 license 누락이 아닙니다.

Build·test·offline 도구

구성요소 lockfile 기준 역할 License·배포 판단
Vite 8.1.5 dev server와 production build MIT. build output에는 runtime third-party notice를 별도로 넣어야 함
TypeScript 7.0.2 typecheck Apache-2.0. compiler를 고객에게 함께 전달하지 않으면 제품 source 공개 영향 없음
Vitest 4.1.10 unit test MIT, 제품 runtime 아님
Playwright 1.62.0 browser E2E Apache-2.0, 제품 runtime 아님
Puppeteer Core 25.4.0 resolved 3D smoke·preview capture Apache-2.0. Chrome binary를 포함하지 않음
Lightning CSS 1.33.0 계열 12 entry Vite build transitive MPL-2.0. build host에서만 사용하며 browser runtime에는 포함되지 않음
Node.js·npm Node >=24, npm >=11 요구 install, build, tool runtime 함께 재배포하면 각 runtime과 bundled dependency license를 별도 감사
Chrome system executable Playwright/Puppeteer 실행 repository가 bundle하지 않음. CI image·설치형 배포에 포함하면 vendor 조건 별도 검토
ffmpeg optional, lockfile 밖 PNG frame을 animated WebP로 결합 binary를 bundle할 때 실제 build option의 LGPL/GPL/nonfree 조건 확인
KTX-Software toktx 도입 안내만 존재 선택적 KTX2 encoding 현재 dependency가 아님. 도입 시 exact binary BOM과 license 재검토

apps/viewer-3d/tools/preprocess.mjs@gltf-transform/core, @gltf-transform/functions, @gltf-transform/extensions, draco3d를 import하지만 현재 package.json과 lockfile에는 이 package들이 없습니다. 따라서 clean install의 정식 toolchain으로 재현되지 않습니다.

현재 script가 구현한 texture output은 WebP/JPEG/PNG이며 KTX2 encoding은 하지 않습니다. KTX2는 별도 glTF Transform CLI와 toktx가 필요합니다. 하위 tools/README.md의 “KTX2 default” 설명은 현재 code와 일치하지 않습니다.

MPL·Apache·OFL 적용 범위

MPL-2.0은 file-level copyleft입니다. 별도 파일로 결합한 이 application 전체를 MPL로 공개할 필요는 없지만, 조직 밖으로 browser JS/WASM executable을 전달하면 수령자가 해당 MPL covered source와 수정분을 합리적인 방법으로 얻을 수 있게 알려야 합니다. browser로 전송되는 client code도 배포에 해당합니다.

  • web-ifc@0.0.77: exact source archive 또는 고정 commit/tag URL과 수정 여부, build 가능한 covered source 취득 안내가 필요
  • acadrust DWG WASM: crate source만으로는 현재 binary wrapper를 재현할 수 없으므로 wrapper source·Cargo/wasm-bindgen 설정·toolchain을 복구하기 전 외부 배포 보류
  • Lightning CSS: node_modules나 build container를 외부에 전달하지 않고 build host에서만 실행하면 application source 공개 범위를 만들지 않음

Apache-2.0의 Draco와 Basis는 source 공개 의무는 없지만 license 사본, 기존 attribution과 upstream NOTICE, 수정 시 변경 고지를 보존해야 합니다. OFL font는 software와 bundle할 수 있지만 copyright와 OFL 전문을 함께 제공해야 하며, Reserved Font Name 조건을 지켜야 합니다.

참조:

Sample asset과 파생 preview

Sample과 preview는 software dependency license와 별개의 저작물입니다. optimized model과 회전 preview도 원본 asset의 license·attribution·변경 표시를 계승해야 합니다.

자산 확인된 출처·license 현재 판단
BasicSample.dwg 2D standalone initial commit에서 이관, 원출처 불명 내부 회귀 test 전용. 외부 demo 배포 보류
simple.dxf 2D standalone initial commit의 최소 fixture 권리자·license 명시가 없어 외부 재배포 승인 필요
Box.glb Khronos sample, Cesium 제공, CC BY 4.0 상업 사용 가능하나 Cesium attribution, license link와 변경 여부 고지가 현재 배포물에 없음
Duck.glb Copyright 2006 Sony Computer Entertainment Inc., SCEA Shared Source License 1.0 비표준 license. 내부 법무 승인 전 외부 배포 보류
Duck.optimized.glb, Duck.webp Duck의 Draco/WebP·preview 파생물 원본 SCEA 승인과 derivative 변경 표시에 종속
Cube.obj, Cube.dae, Cube.ifc, DoublePrecision.ply 파일·commit에 hand-authored/project fixture 정황 프로젝트 권리자와 first-party license가 선언되지 않아 외부 배포 보류
Cube.fbx, sample.mtl history에는 Three.js morph_test와 Blender 정황만 있고 exact 원본 URL·asset license 없음 provenance 복구 또는 제거 전 외부 배포 보류
Cube.*.webp 각 Cube model에서 생성한 24-frame preview 원본 model의 권리·license와 변경 표시에 종속

Box와 Duck의 upstream license:

fixture checksum과 source history는 docs/PROVENANCE.md, acadrust·font checksum은 THIRD_PARTY_NOTICES.md를 기준으로 관리합니다. 현재 provenance 문서는 2D fixture 중심이며 3D asset과 preview derivative chain은 아직 통합되지 않았습니다.

프로젝트 license와 외부 release gate

루트에는 프로젝트 소유 코드에 적용되는 LICENSE와 copyright holder 선언이 없습니다. package.json"private": true는 npm publish 방지 설정일 뿐 외부 이용·수정·재배포 권한을 부여하지 않습니다. 하위 과거 README의 “Viewer2D 포트·샘플 글루 MIT” 문구도 현재 repository의 license grant로 볼 수 없습니다.

다음 조건을 완료하기 전에는 외부 demo, 고객 전달, 설치형 package, public CDN과 commercial SaaS 배포를 승인하지 않습니다.

  • 프로젝트 소유 코드의 권리자와 proprietary/open-source license 결정
  • 2D·3D build artifact에 runtime THIRD_PARTY_NOTICES와 필요한 license 전문 포함
  • acadrust wrapper source·toolchain 복구와 exact WASM 재현 build
  • acadrust 및 web-ifc@0.0.77 covered source의 고정 archive/URL과 취득 안내 제공
  • Draco·Basis Apache license와 upstream NOTICE 보존
  • Box attribution과 sample별 원본 URL·권리자·license·checksum·derivative chain 기록
  • Duck의 내부 법무 승인 또는 승인된 CC0/CC BY asset으로 교체
  • BasicSample.dwg, Cube.fbx, sample.mtl 등 출처 미완료 fixture의 승인 또는 제거
  • 미사용 web-ifc-mt.wasm과 중복 decoder artifact의 배포 필요성 결정
  • runtime/build/sample을 구분한 SBOM과 CI의 unknown-license/provenance gate

설치와 실행

요구 환경은 Node.js 24 이상, npm 11 이상과 WebGL을 지원하는 browser입니다.

npm ci

npm ci는 workspace dependency를 설치한 뒤 3D decoder와 WASM을 staging합니다.

npm run dev:2d
# http://127.0.0.1:5173

npm run dev:3d
# http://127.0.0.1:3333

URL load 예시:

http://127.0.0.1:5173/?model=/samples/simple.dxf
http://127.0.0.1:3333/?model=/samples/Box.glb

Production build와 preview:

npm run build
npm --workspace @hmwebviewer/viewer-2d-sample run preview
npm --workspace @hmwebviewer/viewer-3d run preview

검증

npm run typecheck
npm run test:unit
npm run build
npm run test:e2e

전체 순차 검증:

npm run verify

현재 test가 확인하는 범위:

  • 2D public package interface의 DXF parse
  • 2D same-origin·50 MiB 입력 정책
  • canonical module map 문서 drift
  • decoder WASM의 installed dependency 대비 checksum과 실행 권한
  • Vite subpath의 public asset URL
  • 2D DWG/DXF sample과 local file load
  • 3D GLB, Draco GLB, OBJ, FBX, DAE, IFC, PLY sample render
  • 2D/3D canvas dispose와 반복 page transition
  • production subpath의 Draco·IFC decoder request

이 검증은 sample이 화면에 나타나고 runtime error가 없다는 smoke/contract 수준입니다. engineering 정확도와 외부 배포 compliance를 승인하는 test는 아닙니다.

문서

하위 2D README에는 통합 전 standalone layout이, 3D tools README에는 과거 KTX2 계획이 남아 있습니다. 현재 workspace의 canonical 개요와 배포 판단은 이 문서를 기준으로 하며, 하위 문서는 후속 정합성 정리가 필요합니다.

현재 판정

2D와 3D sample의 주요 load path, lifecycle, decoder staging과 subpath 배포를 검증하는 자동화가 있습니다. 내부 기능 검증용 workspace로는 사용할 수 있습니다.

운영 release에는 format별 정확도 contract, 3D 입력 제한·cancellation·Worker 격리, 프로젝트 license, MPL source 제공, third-party 고지와 sample provenance blocker가 남아 있습니다. 특히 “상업 사용 가능한 dependency”와 “현재 artifact를 조건 없이 상업 배포할 수 있음”은 같은 뜻이 아닙니다.

S
Description
Standalone DWG/DXF 2D viewer sample — compose acadrust-dwg + dxf-parser + Viewer2D (Vite/Three.js)
Readme
8 MiB
Languages
JavaScript 55.6%
TypeScript 31.2%
HTML 12.3%
CSS 0.6%
Shell 0.3%