@flyfish-dev/cad-viewer 0.6.3 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,6 +12,19 @@ The project provides a clean loader architecture for **DWG**, **DXF**, **DWF**,
12
12
 
13
13
  > DWG support uses `@mlightcad/libredwg-web` / LibreDWG WebAssembly in a worker. DXF support uses JavaScript parsing plus a built-in fallback parser. DWF, DWFx and XPS support is powered by `dwf-viewer` 0.6.x, including DWF 6+ ZIP containers, WHIP/W2D 2D sheets, W3D/HSF 3D eModel geometry, DWFx/OPC/XPS pages, adaptive CAD line weights and an optional raster WASM fallback.
14
14
 
15
+ ## What changed in 0.6.5
16
+
17
+ - Preserved active DWG VPORT/header UCS saved views and applied safe planar scene transforms exactly once across geometry, text, inserts, bounds and interaction coordinates.
18
+ - Added DWG LTYPE normalization and Canvas2D/WebGL rendering for dashed, dotted, BYLAYER and BYBLOCK linetypes, including continuous polyline phase and entity/global scale handling.
19
+ - Preserved LibreDWG closed-polyline flags and added guarded fallbacks for tilted views, complex SHX linetype glyphs and pathological microscopic patterns.
20
+ - Added public line-pattern helpers, `getSourceDocument()` and an eight-case DWG normalization regression suite.
21
+
22
+ ## What changed in 0.6.4
23
+
24
+ - Added a stable package export for `@flyfish-dev/cad-viewer/wasm/dwg-worker.js`.
25
+ - DWG worker loading now defaults to the page-relative runtime asset `wasm/dwg-worker.js`, making npm package assets and static demo deployments use the same worker file.
26
+ - Dev, demo, Cloudflare Pages and npm library builds now build and copy the DWG worker asset explicitly before serving or packaging runtime files.
27
+
15
28
  ## What changed in 0.6.3
16
29
 
17
30
  - Added `dxfEncoding` for overriding DXF text decoding when legacy files omit or misdeclare `$DWGCODEPAGE`.
@@ -79,6 +92,7 @@ The project provides a clean loader architecture for **DWG**, **DXF**, **DWF**,
79
92
  - **Pure frontend viewer component**: `new CadViewer({ container })` or `new CadViewer({ canvas })`.
80
93
  - **Loader registry**: DWG, DXF and DWF loaders are independent and replaceable; native-renderable loaders can mount their own optimized viewer.
81
94
  - **DWG preview**: browser-local parsing through LibreDWG WebAssembly, executed in a Web Worker by default.
95
+ - **DWG view and linetype fidelity**: active planar saved views, closed polylines, LTYPE tables, BYLAYER/BYBLOCK inheritance, dash/dot patterns and stable pattern scaling.
82
96
  - **DXF preview**: JavaScript parser path with fallback support for common ASCII DXF `ENTITIES`.
83
97
  - **DWF/DWFx/XPS preview**: powered by `dwf-viewer` for DWF ZIP packages, WebGL-accelerated W2D and XPS/DWFx 2D vectors, W3D/HSF eModel geometry, embedded XPS fonts, adaptive CAD line weights and raster fallback.
84
98
  - **CAD color handling**: ACI, BYLAYER, BYBLOCK inheritance, DWG layer colors, true color, fill color, opacity and adaptive contrast.
@@ -99,16 +113,18 @@ npm install
99
113
  npm run dev
100
114
  ```
101
115
 
102
- The DWG and DWF render paths need runtime WASM assets in a public directory. This repository copies and validates them for the demo:
116
+ The DWG and DWF render paths need runtime assets in a public directory: `libredwg-web.js`, `libredwg-web.wasm`, `dwg-worker.js` and `dwfv-render.wasm`. This repository copies, builds and validates them for the demo:
103
117
 
104
118
  ```bash
105
119
  npm run copy:wasm
120
+ npm run build:worker
121
+ npm run copy:worker
106
122
  npm run check:wasm
107
123
  ```
108
124
 
109
- The demo resolves `wasmPath` to an absolute URL before sending it to the DWG worker and uses the same directory for `dwfv-render.wasm`. In your own app, prefer an absolute path or URL, for example `/wasm` or `new URL('wasm/', document.baseURI).href`. Avoid passing a worker-relative path such as `./wasm` unless it is resolved on the UI thread first.
125
+ The demo resolves `wasmPath` to an absolute URL before sending it to the DWG worker and uses the same directory for `dwfv-render.wasm`. The default DWG worker URL is `wasm/dwg-worker.js`, resolved against the page URL. In your own app, prefer absolute paths or URLs, for example `/wasm`, `/wasm/dwg-worker.js` or `new URL('wasm/', document.baseURI).href`. Avoid passing a worker-relative path such as `./wasm` unless it is resolved on the UI thread first.
110
126
 
111
- When publishing the npm package, `build:lib` copies these files into `dist/wasm` and exposes them as package subpaths. Applications still need to serve the `.wasm` files from a public URL and pass that directory as `wasmPath`, or pass `dwfWasmUrl` explicitly.
127
+ When publishing the npm package, `build:lib` copies these files into `dist/wasm` and exposes them as package subpaths, including `./wasm/dwg-worker.js`. Applications still need to serve the runtime files from a public URL and pass that directory as `wasmPath`, or pass `dwfWasmUrl` / `workerUrl` explicitly.
112
128
 
113
129
 
114
130
  ## Demo startup notes
@@ -198,7 +214,7 @@ For very large drawings, lower `maxCurveSegments`, increase `spatialIndexCellCou
198
214
 
199
215
  ## Worker-backed DWG parsing
200
216
 
201
- `DwgLoader` uses a module Web Worker by default in browsers. The worker imports `@mlightcad/libredwg-web`, initializes LibreDWG WASM inside the worker thread, caches that WASM instance, decodes DWG bytes, normalizes the result into a structured-clone-safe `CadDocument`, and sends only the normalized scene back to the UI thread. Canvas rendering remains on the main thread.
217
+ `DwgLoader` uses a module Web Worker by default in browsers. The default worker URL is `wasm/dwg-worker.js`, resolved relative to the page. The worker imports `@mlightcad/libredwg-web`, initializes LibreDWG WASM inside the worker thread, caches that WASM instance, decodes DWG bytes, normalizes the result into a structured-clone-safe `CadDocument`, and sends only the normalized scene back to the UI thread. Canvas rendering remains on the main thread.
202
218
 
203
219
  ```ts
204
220
  const controller = new AbortController();
@@ -221,7 +237,7 @@ await viewer.loadFile(file, { signal: controller.signal });
221
237
  controller.abort();
222
238
  ```
223
239
 
224
- Advanced deployments can override the worker constructor when the bundler or CDN has a custom asset layout:
240
+ Advanced deployments can override the worker URL or constructor when the bundler or CDN has a custom asset layout:
225
241
 
226
242
  ```ts
227
243
  new CadViewer({
@@ -241,7 +257,7 @@ const viewer = new CadViewer({
241
257
  container, // HTMLElement; creates a canvas inside
242
258
  canvas, // optional existing HTMLCanvasElement
243
259
  renderer: 'auto', // 'auto' | 'webgl' | 'canvas2d'
244
- wasmPath: '/wasm', // directory containing libredwg-web.wasm and dwfv-render.wasm
260
+ wasmPath: '/wasm', // directory containing libredwg-web.js, libredwg-web.wasm and dwfv-render.wasm
245
261
  dxfEncoding: 'gb18030', // optional override when legacy DXF codepage metadata is wrong
246
262
  dwfWasmUrl: '/wasm/dwfv-render.wasm',
247
263
  autoFit: true,
@@ -261,6 +277,7 @@ const viewer = new CadViewer({
261
277
  maxVisibleTextLabels: 2400
262
278
  },
263
279
  useWorker: true, // default for DWG
280
+ workerUrl: '/wasm/dwg-worker.js', // optional override; this is the default path
264
281
  workerTimeoutMs: 0, // 0 = disabled
265
282
  dwfPreferWebgl: true,
266
283
  dwfPreferWasm: true,
@@ -282,6 +299,8 @@ viewer.zoomIn();
282
299
  viewer.zoomOut();
283
300
  await viewer.preloadDwg(); // optional DWG worker/WASM warmup
284
301
  viewer.setCanvasOptions({ background: '#f7f8fb', foreground: '#111827' });
302
+ viewer.getDocument(); // transformed render-space CadDocument
303
+ viewer.getSourceDocument(); // parser-owned WCS CadDocument
285
304
  viewer.clear();
286
305
  viewer.destroy();
287
306
  ```
@@ -346,7 +365,7 @@ viewer.registerLoader({
346
365
 
347
366
  | Format | Loader | Coverage |
348
367
  |---|---|---|
349
- | DWG | `DwgLoader` | Uses LibreDWG WebAssembly. Rendering coverage depends on the entities exposed by LibreDWG conversion. |
368
+ | DWG | `DwgLoader` | Uses LibreDWG WebAssembly. Preserves active planar saved views, closed polylines and LTYPE definitions; Canvas2D/WebGL render dash/dot patterns with BYLAYER/BYBLOCK inheritance. Complex SHX glyphs use a marker approximation. |
350
369
  | DXF | `DxfLoader` | Uses `dxf-parser` plus fallback parsing. Supports codepage-aware text decoding, CAD text escape normalization, core entities, blocks/inserts, colors/layers, polylines, hatch boundaries and splines as preview polylines. |
351
370
  | DWF | `DwfLoader` + `dwf-viewer` | DWF 6+ ZIP packages, WHIP/W2D 2D sheets, W3D/HSF 3D eModel pages, model tree metadata, WebGL rendering and optional WASM fallback. |
352
371
  | DWFx / XPS | `DwfLoader` + `dwf-viewer` | DWFx/OPC/XPS pages with WebGL-accelerated vector paths, embedded fonts, text, images, package resources and adaptive overview line weights through the native DWF renderer. |
@@ -376,6 +395,7 @@ new CadViewer({ canvasOptions: { trueColorByteOrder: 'bgr' } });
376
395
  npm install
377
396
  npm run dev # run the demo
378
397
  npm run typecheck # TypeScript validation
398
+ npm test # build the library and run DWG normalization regressions
379
399
  npm run build # library + demo
380
400
  npm run preview # preview built demo
381
401
  ```
package/README.zh-CN.md CHANGED
@@ -12,6 +12,19 @@
12
12
 
13
13
  > DWG 使用 `@mlightcad/libredwg-web` / LibreDWG WebAssembly,并默认运行在 Worker 中。DXF 使用 JavaScript 解析器并带内置 fallback。DWF、DWFx、XPS 由 `dwf-viewer` 0.6.x 驱动,覆盖 DWF 6+ ZIP 包、WHIP/W2D 2D 图纸、W3D/HSF 3D eModel、DWFx/OPC/XPS 页面、自适应 CAD 线宽和可选 raster WASM fallback。
14
14
 
15
+ ## 0.6.5 变更
16
+
17
+ - 保留 DWG active VPORT/header UCS saved view,并将安全的平面场景变换只应用一次,统一覆盖几何、文字、INSERT、bounds 和交互坐标。
18
+ - 新增 DWG LTYPE 归一化与 Canvas2D/WebGL 线型渲染,支持虚线、点线、BYLAYER、BYBLOCK、多段线连续相位以及实体/全局缩放。
19
+ - 保留 LibreDWG 的闭合多段线标志;对倾斜视图、复杂 SHX 线型 glyph 和异常微小 pattern 提供明确降级策略。
20
+ - 新增公开线型工具、`getSourceDocument()` 和 8 项 DWG normalization 回归测试。
21
+
22
+ ## 0.6.4 变更
23
+
24
+ - 新增稳定的 package subpath:`@flyfish-dev/cad-viewer/wasm/dwg-worker.js`。
25
+ - DWG worker 默认改为页面相对运行时资源 `wasm/dwg-worker.js`,npm 包资源和静态 Demo 部署使用同一份 worker 文件。
26
+ - dev、demo、Cloudflare Pages 和 npm library 构建都会显式构建并复制 DWG worker 运行时资源。
27
+
15
28
  ## 0.6.3 变更
16
29
 
17
30
  - 新增 `dxfEncoding`,用于旧 DXF 缺少或误写 `$DWGCODEPAGE` 时显式指定文本编码。
@@ -79,6 +92,7 @@
79
92
  - **纯前端组件**:`new CadViewer({ container })` 或 `new CadViewer({ canvas })`。
80
93
  - **正确的 loader 架构**:DWG / DXF / DWF 独立 loader,可替换、可扩展;native-renderable loader 可以挂载自己的优化渲染器。
81
94
  - **DWG 预览**:通过 LibreDWG WebAssembly 在浏览器本地解析,默认在 Web Worker 中执行。
95
+ - **DWG 视图与线型保真**:active 平面 saved view、闭合多段线、LTYPE 表、BYLAYER/BYBLOCK 继承、dash/dot pattern 和稳定线型缩放。
82
96
  - **DXF 预览**:JavaScript 解析,支持常见 ASCII DXF `ENTITIES`,并带 fallback parser。
83
97
  - **DWF/DWFx/XPS 预览**:由 `dwf-viewer` 支持 DWF ZIP 包、WebGL 加速 W2D 与 XPS/DWFx 2D 矢量、W3D/HSF eModel、XPS 嵌入字体、自适应 CAD 线宽和 raster fallback。
84
98
  - **CAD 颜色处理**:支持 ACI、BYLAYER、BYBLOCK 继承、DWG 图层颜色、true color、填充色、透明度和自适应对比度。
@@ -99,16 +113,18 @@ npm install
99
113
  npm run dev
100
114
  ```
101
115
 
102
- DWG 和 DWF 渲染链路需要将运行时 WASM 文件放到公开目录。Demo 使用以下命令复制并校验到 `public/wasm`:
116
+ DWG 和 DWF 渲染链路需要把运行时资源放到公开目录:`libredwg-web.js`、`libredwg-web.wasm`、`dwg-worker.js` `dwfv-render.wasm`。Demo 使用以下命令复制、构建并校验到 `public/wasm`:
103
117
 
104
118
  ```bash
105
119
  npm run copy:wasm
120
+ npm run build:worker
121
+ npm run copy:worker
106
122
  npm run check:wasm
107
123
  ```
108
124
 
109
- Demo 会先把 `wasmPath` 解析为绝对 URL,再发送给 DWG worker,并复用同一目录查找 `dwfv-render.wasm`。你自己的应用也建议使用绝对路径或绝对 URL,例如 `/wasm` 或 `new URL('wasm/', document.baseURI).href`。不要直接把未解析的 `./wasm` 传入 worker,否则它可能会相对于 worker chunk 请求资源。
125
+ Demo 会先把 `wasmPath` 解析为绝对 URL,再发送给 DWG worker,并复用同一目录查找 `dwfv-render.wasm`。默认 DWG worker 地址是 `wasm/dwg-worker.js`,相对于页面 URL 解析。你自己的应用也建议使用绝对路径或绝对 URL,例如 `/wasm`、`/wasm/dwg-worker.js` 或 `new URL('wasm/', document.baseURI).href`。不要直接把未解析的 `./wasm` 传入 worker,否则它可能会相对于 worker 请求资源。
110
126
 
111
- 发布 npm 包时,`build:lib` 会把这些文件复制到 `dist/wasm` 并作为 package subpath 暴露出来。应用侧仍需要把 `.wasm` 放到可公开访问的 URL,并把该目录传给 `wasmPath`,或者显式传入 `dwfWasmUrl`。
127
+ 发布 npm 包时,`build:lib` 会把这些文件复制到 `dist/wasm` 并作为 package subpath 暴露出来,包括 `./wasm/dwg-worker.js`。应用侧仍需要把运行时资源放到可公开访问的 URL,并把该目录传给 `wasmPath`,或者显式传入 `dwfWasmUrl` / `workerUrl`。
112
128
 
113
129
 
114
130
  ## Demo 启动说明
@@ -198,7 +214,7 @@ new CadViewer({
198
214
 
199
215
  ## Worker 化 DWG 解析
200
216
 
201
- `DwgLoader` 在浏览器里默认使用 module Web WorkerWorker 内部导入 `@mlightcad/libredwg-web`,初始化 LibreDWG WASM,缓存该 WASM 实例,解码 DWG 字节,并把结果归一化为可 structured-clone 的 `CadDocument` 后发送回 UI 线程。Canvas 渲染仍然留在主线程。
217
+ `DwgLoader` 在浏览器里默认使用 module Web Worker。默认 worker 地址是 `wasm/dwg-worker.js`,相对于页面 URL 解析。Worker 内部导入 `@mlightcad/libredwg-web`,初始化 LibreDWG WASM,缓存该 WASM 实例,解码 DWG 字节,并把结果归一化为可 structured-clone 的 `CadDocument` 后发送回 UI 线程。Canvas 渲染仍然留在主线程。
202
218
 
203
219
  ```ts
204
220
  const controller = new AbortController();
@@ -221,7 +237,7 @@ await viewer.loadFile(file, { signal: controller.signal });
221
237
  controller.abort();
222
238
  ```
223
239
 
224
- 如果你的构建系统或 CDN 对 worker 资源路径有特殊要求,可以显式传入 worker 地址:
240
+ 如果你的构建系统或 CDN 对 worker 资源路径有特殊要求,可以显式传入 worker 地址或构造器:
225
241
 
226
242
  ```ts
227
243
  new CadViewer({
@@ -241,7 +257,7 @@ const viewer = new CadViewer({
241
257
  container, // 容器元素,组件会自动创建 canvas
242
258
  canvas, // 也可以传入已有 canvas
243
259
  renderer: 'auto', // 'auto' | 'webgl' | 'canvas2d'
244
- wasmPath: '/wasm', // LibreDWG WebAssembly 资源路径。Worker 场景建议使用绝对路径/URL
260
+ wasmPath: '/wasm', // 包含 libredwg-web.js、libredwg-web.wasm dwfv-render.wasm 的目录
245
261
  dxfEncoding: 'gb18030', // 可选:旧 DXF codepage 元数据错误时显式指定编码
246
262
  dwfWasmUrl: '/wasm/dwfv-render.wasm',
247
263
  autoFit: true,
@@ -261,6 +277,7 @@ const viewer = new CadViewer({
261
277
  maxVisibleTextLabels: 2400
262
278
  },
263
279
  useWorker: true, // DWG 默认开启
280
+ workerUrl: '/wasm/dwg-worker.js', // 可选覆盖;这是默认地址
264
281
  workerTimeoutMs: 0, // 0 表示不限制
265
282
  dwfPreferWebgl: true,
266
283
  dwfPreferWasm: true,
@@ -282,6 +299,8 @@ viewer.zoomIn();
282
299
  viewer.zoomOut();
283
300
  await viewer.preloadDwg(); // 可选 DWG worker/WASM 预热
284
301
  viewer.setCanvasOptions({ background: '#f7f8fb', foreground: '#111827' });
302
+ viewer.getDocument(); // 已应用 saved view 的渲染场景 CadDocument
303
+ viewer.getSourceDocument(); // parser 保留的原始 WCS CadDocument
285
304
  viewer.clear();
286
305
  viewer.destroy();
287
306
  ```
@@ -346,7 +365,7 @@ viewer.registerLoader({
346
365
 
347
366
  | 格式 | Loader | 支持范围 |
348
367
  |---|---|---|
349
- | DWG | `DwgLoader` | 使用 LibreDWG WebAssembly。渲染完整度取决于 LibreDWG converter 暴露出的实体。 |
368
+ | DWG | `DwgLoader` | 使用 LibreDWG WebAssembly。保留 active 平面 saved view、闭合多段线和 LTYPE 定义;Canvas2D/WebGL 支持 dash/dot 与 BYLAYER/BYBLOCK 继承,复杂 SHX glyph 使用 marker 近似。 |
350
369
  | DXF | `DxfLoader` | 使用 `dxf-parser` + 内置 fallback。支持 codepage-aware 文本解码、CAD 文本转义归一化、基础实体、block/insert、颜色/图层、多段线、hatch boundary、spline 预览。 |
351
370
  | DWF | `DwfLoader` + `dwf-viewer` | DWF 6+ ZIP 包、WHIP/W2D 2D 图纸、W3D/HSF 3D eModel、模型树元数据、WebGL 渲染和可选 WASM fallback。 |
352
371
  | DWFx / XPS | `DwfLoader` + `dwf-viewer` | DWFx/OPC/XPS 页面,包含 WebGL 加速 vector path、嵌入字体、文本、图片、包内资源和自适应总览线宽,通过原生 DWF 渲染器展示。 |
@@ -376,6 +395,7 @@ new CadViewer({ canvasOptions: { trueColorByteOrder: 'bgr' } });
376
395
  npm install
377
396
  npm run dev # 运行 demo
378
397
  npm run typecheck # TypeScript 检查
398
+ npm test # 构建 library 并运行 DWG normalization 回归测试
379
399
  npm run build # 构建 library + demo
380
400
  npm run preview # 预览构建后的 demo
381
401
  ```