This repository has no deploy script or CI: package.json only builds to
dist/ (gitignored), yet dist2/ is committed and is what actually gets
served. The procedure was folklore reconstructed from commit history each
time someone deployed.
Write it down, including the two traps found while deploying fb8f7ca:
- vite's emptyOutDir defaults to true when outDir sits inside the project
root, so a bare `vite build --outDir dist2` deletes the hand-placed test
assets in dist2/samples (configBak/, dwg_18.3mb.dwg). Always pass
--emptyOutDir false.
- npx vite can fail here with `Missing script: "vite"`; call
./node_modules/.bin/vite directly.
Also notes the open issues: no build:dist2 script, old hashed bundles
accumulating in dist2/assets, and test fixtures living inside the build
output directory.
Link it from the README issue table.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
setHiddenLayers() called load(result, {keepView:true}), so every layer
on/off re-parsed and re-tessellated the whole drawing — arc sampling,
hatch triangulation, complex linetypes and the Slug text batch all rebuilt
from scratch. On an 18 MB DWG a single eye-icon click took 5 s+.
Build every layer once, then switch geometry on and off:
- Merged LineSegments buffers get an index buffer plus a per-segment layer
id (_registerIndexed). A toggle rewrites the index and setDrawRange;
positions, colors and lineDistances are untouched, so draw order, dash
phase and the selection-highlight offsets in meta.colStart stay valid.
- Per-entity meshes (hatch fills, SOLID quads, arrowheads, OLE images,
sprites) are tagged by layer via _addObj and toggled with .visible.
- Slug text builds one merged mesh per CAD layer instead of one per
draw order, so text hides with a visible flag. The shader source is
identical across batches, so three still shares one WebGLProgram.
- Hidden geometry stays in the pick buffers, so _onClick now skips it via
the _metaHidden mask.
- Fit keeps framing only what is drawn: per-layer Box3 + fit samples are
recorded at build and unioned over the visible layers.
- getLayerInfo() caches the O(entities) name/color/count pass per load;
only the visible flag is recomputed.
Layer panel: one delegated click listener instead of re-binding a handler
per row, and a toggle patches the affected row's opacity/icon in place
rather than regenerating the whole list's innerHTML.
Trade-off: hidden layers are now built and kept in memory, so loading a
file with layers already off costs what a full load costs.
Rebuilds dist2.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
SlugTextBatch.add() scaled em-unit glyph outlines by the raw DWG
`height` value, but glyph ink only reaches capHeightEm (~0.74 em) of
the em box. Rendered cap height ended up ~26% short of spec (e.g. a
3.6-height TABLE cell text rendered at ~2.68), while the canvas-sprite
fallback already corrected for this via measured ascent. Divide by
capHeightEm so both paths agree.
Rebuilds dist2 (was stale since before the Entity selection/Property
Inspector/Layer panel work landed).
Mirrors hmwebviewer's rust/dwg-wasm change into the sample: the wasm
artifact plus the parser wrapper, which now goes through parse_dwg_json
and JSON.parse instead of the JsValue-returning parse_dwg.
Building the whole result as a serde_json::Value tree pushed the live
wasm heap near 2.9GB for a 19MB drawing, and the allocator's cost grows
with that heap, so parsing went quadratic — 354s, with the tab frozen
throughout. Streaming one entity at a time keeps it linear: 2.5s.
The same build also fixes three bugs that drew stray 4km grey shapes
where two CF-PATT SOLID hatches should be. Max hatch span 4655 -> 110.
Adds two docs recording both investigations, in the format of the
existing ones: measurements, the hypotheses that were ruled out, the
fixes, regression checks, and the MPL-2.0 position (acadrust is
unmodified, so no new source-disclosure obligation arises).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>