refactor: establish unified viewer workspaces
This commit is contained in:
@@ -1,113 +1,21 @@
|
||||
# dwg-dxf-viewer-sample
|
||||
# hmwebviewer workspace
|
||||
|
||||
**hmwebviewer 형제 폴더**에 분리된 DWG/DXF 2D 뷰어 샘플입니다.
|
||||
Three.js 기반 3D viewer와 DWG/DXF 2D viewer sample을 한 저장소에서 관리합니다.
|
||||
|
||||
`docs/modules-dwg-dxf.html` 모듈 지도의 카드
|
||||
(`acadrust-dwg`, `dxf-parser`, `Viewer2D` …)를 **직접 조합**해 동작하는 독립 프로젝트입니다.
|
||||
`hmwebviewer` 저장소 안에 의존하지 않습니다.
|
||||
이 저장소의 구조 통합과 검증 계획은 Gitea issue #5를 기준으로 진행합니다.
|
||||
|
||||
```
|
||||
D:\MYCLAUDE_PROJECT\
|
||||
hmwebviewer\ ← 본 제품
|
||||
dwg-dxf-viewer-sample\ ← 이 샘플 (형제)
|
||||
```
|
||||
## Workspace
|
||||
|
||||
---
|
||||
- `@hmwebviewer/viewer-3d`: 기존 3D viewer application
|
||||
- `@hmwebviewer/viewer-2d-sample`: DWG/DXF sample application
|
||||
- `@hmwebviewer/viewer2d`: 재사용 가능한 DWG/DXF parser와 renderer module
|
||||
|
||||
## 실행
|
||||
|
||||
```bash
|
||||
cd D:\MYCLAUDE_PROJECT\dwg-dxf-viewer-sample
|
||||
npm install
|
||||
npm run dev
|
||||
# → http://localhost:5173
|
||||
npm ci
|
||||
npm run dev:2d
|
||||
npm run dev:3d
|
||||
```
|
||||
|
||||
| UI | 모듈 경로 |
|
||||
|----|-----------|
|
||||
| **Sample DWG** | `ext2d` → **acadrust-dwg WASM** → `Viewer2D` |
|
||||
| **Sample DXF** | `ext2d` → **dxf-parser + hatch + adapter** → `Viewer2D` |
|
||||
| 파일 드롭 / Open | 확장자로 위 둘 중 하나 |
|
||||
|
||||
모듈 지도: 브라우저에서 [`docs/modules-dwg-dxf.html`](./docs/modules-dwg-dxf.html)
|
||||
조합 코드: [`src/main.ts`](./src/main.ts)
|
||||
|
||||
---
|
||||
|
||||
## 레이아웃
|
||||
|
||||
```
|
||||
dwg-dxf-viewer-sample/
|
||||
docs/modules-dwg-dxf.html # 모듈 조합 레시피 HTML
|
||||
public/
|
||||
fonts/NanumGothic-Regular.ttf
|
||||
samples/BasicSample.dwg
|
||||
samples/simple.dxf
|
||||
src/
|
||||
main.ts # 모듈을 import 해서 조립
|
||||
viewer2d/ # 재사용 모듈 본체
|
||||
acadrust-dwg/ # WASM
|
||||
Viewer2D.js
|
||||
dwgParser.ts
|
||||
parseDxf.ts
|
||||
dxfAdapter.js
|
||||
dxfHatchHandler.js
|
||||
ext2d.ts
|
||||
slugText.ts
|
||||
…
|
||||
package.json
|
||||
vite.config.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 조합 파이프라인
|
||||
|
||||
```
|
||||
File/URL
|
||||
→ ext2d (isDwg / isDxf)
|
||||
→ parseDwgBuffer | parseDxfBuffer
|
||||
│ │
|
||||
└ acadrust-dwg ├ decodeDxf
|
||||
├ dxf-parser + dxfHatchHandler
|
||||
└ dxfAdapter
|
||||
→ CadParseResult
|
||||
→ Viewer2D.load() (+ three, slugText/font)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 의존성
|
||||
|
||||
| 패키지 | 역할 |
|
||||
|--------|------|
|
||||
| `three` | WebGL 렌더 / OrbitControls |
|
||||
| `dxf-parser` | DXF 텍스트 파싱 |
|
||||
| `opentype.js` | TTF 글리프 (slugText) |
|
||||
|
||||
WASM(`acadrust_dwg_bg.wasm`)은 `src/viewer2d/acadrust-dwg/` 에 포함되어 있으며
|
||||
Vite `?url` import 로 로드됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 다른 앱에 이식
|
||||
|
||||
1. `src/viewer2d/` 폴더 복사
|
||||
2. `npm i three dxf-parser opentype.js`
|
||||
3. 폰트 `public/fonts/NanumGothic-Regular.ttf`
|
||||
4. Vite: `assetsInclude: ['**/*.wasm']`
|
||||
5. `src/main.ts` 의 ①~④ 블록을 호스트에 붙이고 ⑤ UI만 교체
|
||||
|
||||
소스 동기화(선택): 본가 `hmwebviewer/src/viewer2d` 가 업데이트되면 해당 파일을
|
||||
이 프로젝트 `src/viewer2d` 로 다시 복사하면 됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 라이선스 메모
|
||||
|
||||
| 조각 | 라이선스 |
|
||||
|------|----------|
|
||||
| Viewer2D 포트 · 샘플 글루 | MIT (hmwebviewer 계열) |
|
||||
| acadrust (WASM 내부) | MPL-2.0 |
|
||||
| dxf-parser · three | MIT |
|
||||
| NanumGothic | OFL |
|
||||
전체 검증은 `npm run verify`로 실행합니다.
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# dwg-dxf-viewer-sample
|
||||
|
||||
**hmwebviewer 형제 폴더**에 분리된 DWG/DXF 2D 뷰어 샘플입니다.
|
||||
|
||||
`docs/modules-dwg-dxf.html` 모듈 지도의 카드
|
||||
(`acadrust-dwg`, `dxf-parser`, `Viewer2D` …)를 **직접 조합**해 동작하는 독립 프로젝트입니다.
|
||||
`hmwebviewer` 저장소 안에 의존하지 않습니다.
|
||||
|
||||
```
|
||||
D:\MYCLAUDE_PROJECT\
|
||||
hmwebviewer\ ← 본 제품
|
||||
dwg-dxf-viewer-sample\ ← 이 샘플 (형제)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 실행
|
||||
|
||||
```bash
|
||||
cd D:\MYCLAUDE_PROJECT\dwg-dxf-viewer-sample
|
||||
npm install
|
||||
npm run dev
|
||||
# → http://localhost:5173
|
||||
```
|
||||
|
||||
| UI | 모듈 경로 |
|
||||
|----|-----------|
|
||||
| **Sample DWG** | `ext2d` → **acadrust-dwg WASM** → `Viewer2D` |
|
||||
| **Sample DXF** | `ext2d` → **dxf-parser + hatch + adapter** → `Viewer2D` |
|
||||
| 파일 드롭 / Open | 확장자로 위 둘 중 하나 |
|
||||
|
||||
모듈 지도: 브라우저에서 [`docs/modules-dwg-dxf.html`](./docs/modules-dwg-dxf.html)
|
||||
조합 코드: [`src/main.ts`](./src/main.ts)
|
||||
|
||||
---
|
||||
|
||||
## 레이아웃
|
||||
|
||||
```
|
||||
dwg-dxf-viewer-sample/
|
||||
docs/modules-dwg-dxf.html # 모듈 조합 레시피 HTML
|
||||
public/
|
||||
fonts/NanumGothic-Regular.ttf
|
||||
samples/BasicSample.dwg
|
||||
samples/simple.dxf
|
||||
src/
|
||||
main.ts # 모듈을 import 해서 조립
|
||||
viewer2d/ # 재사용 모듈 본체
|
||||
acadrust-dwg/ # WASM
|
||||
Viewer2D.js
|
||||
dwgParser.ts
|
||||
parseDxf.ts
|
||||
dxfAdapter.js
|
||||
dxfHatchHandler.js
|
||||
ext2d.ts
|
||||
slugText.ts
|
||||
…
|
||||
package.json
|
||||
vite.config.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 조합 파이프라인
|
||||
|
||||
```
|
||||
File/URL
|
||||
→ ext2d (isDwg / isDxf)
|
||||
→ parseDwgBuffer | parseDxfBuffer
|
||||
│ │
|
||||
└ acadrust-dwg ├ decodeDxf
|
||||
├ dxf-parser + dxfHatchHandler
|
||||
└ dxfAdapter
|
||||
→ CadParseResult
|
||||
→ Viewer2D.load() (+ three, slugText/font)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 의존성
|
||||
|
||||
| 패키지 | 역할 |
|
||||
|--------|------|
|
||||
| `three` | WebGL 렌더 / OrbitControls |
|
||||
| `dxf-parser` | DXF 텍스트 파싱 |
|
||||
| `opentype.js` | TTF 글리프 (slugText) |
|
||||
|
||||
WASM(`acadrust_dwg_bg.wasm`)은 `src/viewer2d/acadrust-dwg/` 에 포함되어 있으며
|
||||
Vite `?url` import 로 로드됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 다른 앱에 이식
|
||||
|
||||
1. `src/viewer2d/` 폴더 복사
|
||||
2. `npm i three dxf-parser opentype.js`
|
||||
3. 폰트 `public/fonts/NanumGothic-Regular.ttf`
|
||||
4. Vite: `assetsInclude: ['**/*.wasm']`
|
||||
5. `src/main.ts` 의 ①~④ 블록을 호스트에 붙이고 ⑤ UI만 교체
|
||||
|
||||
소스 동기화(선택): 본가 `hmwebviewer/src/viewer2d` 가 업데이트되면 해당 파일을
|
||||
이 프로젝트 `src/viewer2d` 로 다시 복사하면 됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 라이선스 메모
|
||||
|
||||
| 조각 | 라이선스 |
|
||||
|------|----------|
|
||||
| Viewer2D 포트 · 샘플 글루 | MIT (hmwebviewer 계열) |
|
||||
| acadrust (WASM 내부) | MPL-2.0 |
|
||||
| dxf-parser · three | MIT |
|
||||
| NanumGothic | OFL |
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "@hmwebviewer/viewer-2d-sample",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --port 5173 --strictPort",
|
||||
"build": "tsc --noEmit && vite build",
|
||||
"preview": "vite preview",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hmwebviewer/viewer2d": "*",
|
||||
"three": "0.185.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src/**/*", "vite.config.ts"]
|
||||
}
|
||||
Generated
-4304
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "hmwebviewer",
|
||||
"name": "@hmwebviewer/viewer-3d",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
@@ -8,21 +8,13 @@
|
||||
"build": "tsc --noEmit && vite build",
|
||||
"preview": "vite preview",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"postinstall": "node tools/copy-decoders.mjs"
|
||||
"stage:decoders": "node tools/copy-decoders.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"three": "^0.169.0",
|
||||
"web-ifc": "^0.0.77"
|
||||
"three": "0.185.1",
|
||||
"web-ifc": "0.0.77"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gltf-transform/cli": "^4.4.0",
|
||||
"@gltf-transform/core": "^4.4.0",
|
||||
"@gltf-transform/extensions": "^4.4.0",
|
||||
"@gltf-transform/functions": "^4.4.0",
|
||||
"@types/three": "^0.169.0",
|
||||
"draco3d": "^1.5.7",
|
||||
"puppeteer-core": "^25.1.0",
|
||||
"typescript": "^5.6.0",
|
||||
"vite": "^5.4.0"
|
||||
"puppeteer-core": "^25.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ Both are dependencies of `KTX2Loader`:
|
||||
|
||||
```js
|
||||
const ktx2Loader = new KTX2Loader();
|
||||
ktx2Loader.setTranscoderPath( 'examples/jsm/libs/basis/' );
|
||||
ktx2Loader.detectSupport( renderer );
|
||||
ktx2Loader.load( 'diffuse.ktx2', function ( texture ) {
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Three.js r185 Float64 normalization fixture
|
||||
element vertex 3
|
||||
property double x
|
||||
property double y
|
||||
property double z
|
||||
property uchar red
|
||||
property uchar green
|
||||
property uchar blue
|
||||
element face 1
|
||||
property list uchar int vertex_indices
|
||||
end_header
|
||||
0.0 0.0 0.0 255 0 0
|
||||
100.0 0.0 0.0 0 255 0
|
||||
0.0 100.0 0.0 0 0 255
|
||||
3 0 1 2
|
||||
Regular → Executable
Regular → Executable
@@ -62,6 +62,21 @@ async function getPLY(): Promise<PLYLoaderT> {
|
||||
return (_ply = new PLYLoader());
|
||||
}
|
||||
|
||||
function normalizePlyAttributes(geometry: THREE.BufferGeometry): void {
|
||||
for (const name of ['position', 'normal', 'uv', 'color']) {
|
||||
const attribute = geometry.getAttribute(name);
|
||||
if (!attribute || !(attribute.array instanceof Float64Array)) continue;
|
||||
geometry.setAttribute(
|
||||
name,
|
||||
new THREE.Float32BufferAttribute(
|
||||
new Float32Array(attribute.array),
|
||||
attribute.itemSize,
|
||||
attribute.normalized,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load any supported model URL and resolve to a scene-addable Object3D.
|
||||
* `nameHint` carries the real file name for ext detection when `url` is a
|
||||
@@ -165,7 +180,18 @@ export async function loadModel(
|
||||
case 'dae': {
|
||||
const loader = await getCollada();
|
||||
return new Promise<THREE.Object3D>((resolve, reject) => {
|
||||
loader.load(url, (result) => resolve(result.scene), onXhr, (err) => reject(err));
|
||||
loader.load(
|
||||
url,
|
||||
(result) => {
|
||||
if (!result) {
|
||||
reject(new Error('Collada loader returned no scene'));
|
||||
return;
|
||||
}
|
||||
resolve(result.scene);
|
||||
},
|
||||
onXhr,
|
||||
(err) => reject(err),
|
||||
);
|
||||
});
|
||||
}
|
||||
case 'ply': {
|
||||
@@ -174,6 +200,7 @@ export async function loadModel(
|
||||
loader.load(
|
||||
url,
|
||||
(geometry) => {
|
||||
normalizePlyAttributes(geometry);
|
||||
const hasColor = geometry.hasAttribute('color');
|
||||
if (geometry.index) {
|
||||
// Triangle mesh
|
||||
|
||||
@@ -2,14 +2,16 @@
|
||||
// runtime paths /draco/ and /basis/ resolve (version-matched to installed three).
|
||||
// Also copies the web-ifc single-thread WASM to public/web-ifc/ for the IFC path.
|
||||
// Runs automatically via `npm install` (postinstall). Safe to re-run.
|
||||
import { cpSync, copyFileSync, existsSync, mkdirSync } from 'node:fs';
|
||||
import { cpSync, copyFileSync, existsSync, mkdirSync, rmSync } from 'node:fs';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, '..');
|
||||
|
||||
const libs = resolve(root, 'node_modules/three/examples/jsm/libs');
|
||||
const threeEntry = fileURLToPath(import.meta.resolve('three'));
|
||||
const threeRoot = resolve(dirname(threeEntry), '..');
|
||||
const libs = resolve(threeRoot, 'examples/jsm/libs');
|
||||
const targets = [
|
||||
[resolve(libs, 'draco/gltf'), resolve(root, 'public/draco')],
|
||||
[resolve(libs, 'basis'), resolve(root, 'public/basis')],
|
||||
@@ -25,13 +27,15 @@ for (const [src, dest] of targets) {
|
||||
console.warn(`[copy-decoders] source missing: ${src}`);
|
||||
continue;
|
||||
}
|
||||
rmSync(dest, { force: true, recursive: true });
|
||||
mkdirSync(dest, { recursive: true });
|
||||
cpSync(src, dest, { recursive: true });
|
||||
console.log(`[copy-decoders] ${src} -> ${dest}`);
|
||||
}
|
||||
|
||||
// web-ifc single-thread WASM (+ MT build if present) for the IFC load path.
|
||||
const ifcSrcDir = resolve(root, 'node_modules/web-ifc');
|
||||
const ifcEntry = fileURLToPath(import.meta.resolve('web-ifc'));
|
||||
const ifcSrcDir = dirname(ifcEntry);
|
||||
const ifcDest = resolve(root, 'public/web-ifc');
|
||||
if (existsSync(ifcSrcDir)) {
|
||||
mkdirSync(ifcDest, { recursive: true });
|
||||
|
||||
@@ -7,7 +7,9 @@ export default defineConfig({
|
||||
sourcemap: true,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: { three: ['three'] },
|
||||
manualChunks(id) {
|
||||
if (id.includes('/node_modules/three/')) return 'three';
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Generated
+365
-8
@@ -1,25 +1,46 @@
|
||||
{
|
||||
"name": "dwg-dxf-viewer-sample",
|
||||
"version": "0.1.0",
|
||||
"name": "hmwebviewer-workspace",
|
||||
"version": "0.2.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "dwg-dxf-viewer-sample",
|
||||
"version": "0.1.0",
|
||||
"name": "hmwebviewer-workspace",
|
||||
"version": "0.2.0",
|
||||
"hasInstallScript": true,
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"packages/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"@hmwebviewer/viewer2d": "workspace:*",
|
||||
"three": "0.185.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.62.0",
|
||||
"@types/three": "0.185.1",
|
||||
"typescript": "7.0.2",
|
||||
"vite": "8.1.5",
|
||||
"vitest": "4.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=24.0.0",
|
||||
"npm": ">=11.0.0"
|
||||
}
|
||||
},
|
||||
"apps/viewer-2d-sample": {
|
||||
"name": "@hmwebviewer/viewer-2d-sample",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hmwebviewer/viewer2d": "*",
|
||||
"three": "0.185.1"
|
||||
}
|
||||
},
|
||||
"apps/viewer-3d": {
|
||||
"name": "@hmwebviewer/viewer-3d",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"three": "0.185.1",
|
||||
"web-ifc": "0.0.77"
|
||||
},
|
||||
"devDependencies": {
|
||||
"puppeteer-core": "^25.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@dimforge/rapier3d-compat": {
|
||||
@@ -66,6 +87,14 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@hmwebviewer/viewer-2d-sample": {
|
||||
"resolved": "apps/viewer-2d-sample",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@hmwebviewer/viewer-3d": {
|
||||
"resolved": "apps/viewer-3d",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@hmwebviewer/viewer2d": {
|
||||
"resolved": "packages/viewer2d",
|
||||
"link": true
|
||||
@@ -125,6 +154,35 @@
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.6.tgz",
|
||||
"integrity": "sha512-B/gKoqlFkzhvzsI6jo9K1cZz9o5ypviVv/xu8CwA4grZzyVwN+XfkT+tu8T1zrauuEXv6VhS2oGX+6NL95WcKA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"modern-tar": "^0.7.6",
|
||||
"yargs": "^18.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"browsers": "lib/main-cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"proxy-agent": ">=8.0.1",
|
||||
"yauzl": "^2.10.0 || ^3.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"proxy-agent": {
|
||||
"optional": true
|
||||
},
|
||||
"yauzl": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm64": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz",
|
||||
@@ -973,6 +1031,19 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/assertion-error": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
||||
@@ -993,6 +1064,94 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/chromium-bidi": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-17.0.2.tgz",
|
||||
"integrity": "sha512-5v9GQFhTktFvotn/OFNJBmKLKRAb6n9r0bVCwf7sHgWc3/JryK0bj1nn93L3pHFrfgcsu6Be6EWsDi+1XHTGDg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"mitt": "^3.0.1",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.0 <22.0.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"devtools-protocol": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
|
||||
"integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^7.2.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/ansi-styles": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
|
||||
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/emoji-regex": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
|
||||
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cliui/node_modules/string-width": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
|
||||
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^10.3.0",
|
||||
"get-east-asian-width": "^1.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/wrap-ansi": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
|
||||
"integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.2.1",
|
||||
"string-width": "^7.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
@@ -1010,6 +1169,13 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/devtools-protocol": {
|
||||
"version": "0.0.1653615",
|
||||
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1653615.tgz",
|
||||
"integrity": "sha512-pGVkY3T/qXxAp2nFPodwYqOevk6ncNMSmvL8QfRCx5ZWGd6Vor7AFNmyaA8Zs6uJyP1QAfjuLandCgvSix1BNA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/dxf-parser": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/dxf-parser/-/dxf-parser-1.1.2.tgz",
|
||||
@@ -1026,6 +1192,16 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
@@ -1086,6 +1262,29 @@
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/get-east-asian-width": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
|
||||
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss": {
|
||||
"version": "1.33.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
|
||||
@@ -1389,6 +1588,23 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mitt": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/modern-tar": {
|
||||
"version": "0.7.7",
|
||||
"resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.7.tgz",
|
||||
"integrity": "sha512-t9VmxaqrmANnEOBhpSDI6HD192Ge48k8vmWqQQL7hSFEqHEYwZbbsu49+aKLWZeRvFs3j1pMhXOqqF4kPlvjkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.16",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
|
||||
@@ -1519,6 +1735,24 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/puppeteer-core": {
|
||||
"version": "25.4.0",
|
||||
"resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.4.0.tgz",
|
||||
"integrity": "sha512-K1plkLOdeoUnGeT1OvdqF3qxl33v+Ra/uH5VyPEhXdMcpvGiEskHzxxEU3fgpccJpJLIipB/rPUsvkZRWeKqOA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@puppeteer/browsers": "3.0.6",
|
||||
"chromium-bidi": "17.0.2",
|
||||
"devtools-protocol": "0.0.1653615",
|
||||
"typed-query-selector": "^2.12.2",
|
||||
"webdriver-bidi-protocol": "0.4.2",
|
||||
"ws": "^8.21.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz",
|
||||
@@ -1584,6 +1818,22 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
|
||||
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/three": {
|
||||
"version": "0.185.1",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.185.1.tgz",
|
||||
@@ -1642,6 +1892,13 @@
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/typed-query-selector": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz",
|
||||
"integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz",
|
||||
@@ -1860,6 +2117,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/web-ifc": {
|
||||
"version": "0.0.77",
|
||||
"resolved": "https://registry.npmjs.org/web-ifc/-/web-ifc-0.0.77.tgz",
|
||||
"integrity": "sha512-VzQ0W/Iiqbidxn1ECUvz6qJ6p2sXBVNcOsUOBCETzy77psAH6yFLKQm74aXabkx3JH4OvFVHe8k1qS6+Z2zl1w==",
|
||||
"license": "MPL-2.0"
|
||||
},
|
||||
"node_modules/webdriver-bidi-protocol": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.2.tgz",
|
||||
"integrity": "sha512-VSV+fzfChirL3e7jay2yUC7B4HQCGtEWEg/MSSQbK+qWbqeGlRLlXTzPpYr3XGUvbpDHumWZBJxgesg4N7dbtA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/why-is-node-running": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
|
||||
@@ -1877,6 +2147,93 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.21.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
|
||||
"integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "18.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz",
|
||||
"integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^9.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"string-width": "^8.2.1",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^22.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "22.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
|
||||
"integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/string-width": {
|
||||
"version": "8.2.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz",
|
||||
"integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"get-east-asian-width": "^1.5.0",
|
||||
"strip-ansi": "^7.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.25.76",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
},
|
||||
"packages/viewer2d": {
|
||||
"name": "@hmwebviewer/viewer2d",
|
||||
"version": "0.1.0",
|
||||
|
||||
+16
-13
@@ -1,23 +1,22 @@
|
||||
{
|
||||
"name": "dwg-dxf-viewer-sample",
|
||||
"name": "hmwebviewer-workspace",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"description": "Standalone sample: compose acadrust-dwg + dxf-parser + Viewer2D (sibling of hmwebviewer)",
|
||||
"version": "0.2.0",
|
||||
"type": "module",
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"packages/*"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "vite --port 5173 --strictPort",
|
||||
"build": "tsc --noEmit && vite build",
|
||||
"preview": "vite preview",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "vitest run",
|
||||
"test:unit": "vitest run tests/viewer2d.contract.test.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hmwebviewer/viewer2d": "workspace:*",
|
||||
"three": "0.185.1"
|
||||
"dev:2d": "npm --workspace @hmwebviewer/viewer-2d-sample run dev",
|
||||
"dev:3d": "npm --workspace @hmwebviewer/viewer-3d run dev",
|
||||
"build": "npm run build --workspaces --if-present",
|
||||
"typecheck": "npm run typecheck --workspaces --if-present",
|
||||
"test": "npm run test:unit",
|
||||
"test:unit": "vitest run",
|
||||
"test:e2e": "playwright test",
|
||||
"verify": "npm run typecheck && npm run test:unit && npm run build && npm run test:e2e",
|
||||
"postinstall": "npm --workspace @hmwebviewer/viewer-3d run stage:decoders"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.62.0",
|
||||
@@ -25,5 +24,9 @@
|
||||
"typescript": "7.0.2",
|
||||
"vite": "8.1.5",
|
||||
"vitest": "4.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=24.0.0",
|
||||
"npm": ">=11.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/// <reference path="./shims.d.ts" />
|
||||
|
||||
import { Viewer2D } from './Viewer2D.js';
|
||||
import { parseDwgBuffer, type CadParseResult } from './dwgParser';
|
||||
import { is2D, isDwg } from './ext2d';
|
||||
|
||||
@@ -4,7 +4,9 @@ import { isCad2DFile, parseCad } from '@hmwebviewer/viewer2d';
|
||||
|
||||
describe('viewer2d package interface', () => {
|
||||
it('parses the sample DXF through the public package interface', async () => {
|
||||
const file = await readFile(new URL('../public/samples/simple.dxf', import.meta.url));
|
||||
const file = await readFile(
|
||||
new URL('../apps/viewer-2d-sample/public/samples/simple.dxf', import.meta.url),
|
||||
);
|
||||
const result = await parseCad({
|
||||
name: 'simple.dxf',
|
||||
data: file.buffer.slice(file.byteOffset, file.byteOffset + file.byteLength),
|
||||
|
||||
+1
-2
@@ -10,6 +10,5 @@
|
||||
"esModuleInterop": true,
|
||||
"isolatedModules": true,
|
||||
"allowJs": true
|
||||
},
|
||||
"include": ["src/**/*", "packages/*/src/**/*", "vite.config.ts"]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user