fix(viewer2d): show lineweight at AutoCAD's display scale (20 px/mm)
Hand test against an AutoCAD capture: the 0.50mm road edge is ~10px there but only ~4px here. Lineweight is zoom-independent screen pixels, so the two captures compare directly - the 8 px/mm mapping was 2.5x too small. AutoCAD's default display scale is one pixel per 0.05mm, so use 20 px/mm (0.35mm = 7px, 0.50mm = 10px, 2.11mm = 42px) and raise the clamp to 48px. Add setLineweightScale()/getLineweightScale() so a host can retune it - AutoCAD exposes the same thing as the Adjust Display Scale slider. Re-measured headless: the 0.35mm road-gutter line now renders ~7px, so both weight classes land on the same scale. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,15 +25,17 @@ const CLICK_THRESHOLD_PX = 14;
|
||||
// ── Lineweight (AutoCAD LWDISPLAY) ─────────────────────────────────────────
|
||||
// DWG stores lineweight as an i16 in 1/100 mm (-1 ByLayer, -2 ByBlock,
|
||||
// -3 Default). AutoCAD shows it in *screen* pixels — the width does not grow
|
||||
// when you zoom in — at roughly 8 px per mm on the default display-scale
|
||||
// slider (0.25 mm ≈ 2 px, 2.11 mm ≈ 17 px), so that is the mapping used here.
|
||||
const LW_PX_PER_MM = 8;
|
||||
// when you zoom in — at one pixel per 0.05 mm on the default display-scale
|
||||
// slider (0.50 mm = 10 px, 2.11 mm = 42 px). Measured against an AutoCAD
|
||||
// capture of the 노면 drawing: its 0.50 mm road edge is ~10 px, so 20 px/mm.
|
||||
// Host apps can retune this with setLineweightScale().
|
||||
const LW_PX_PER_MM = 20;
|
||||
// LWDEFAULT: what -3 (and a layer that never set one) resolves to.
|
||||
const LW_DEFAULT_MM = 0.25;
|
||||
// At or below the CAD default the line stays in the 1-px hairline batch: a
|
||||
// drawing that never assigned weights must look exactly as it did before.
|
||||
const LW_HAIRLINE_MM = 0.25;
|
||||
const LW_MAX_PX = 24;
|
||||
const LW_MAX_PX = 48;
|
||||
// Fat lines cost 12 floats + 8 verts per segment (instanced quads). Past this
|
||||
// many segments in one weight bucket, fall back to hairline instead of risking
|
||||
// a GPU/heap stall on huge survey drawings.
|
||||
@@ -105,6 +107,7 @@ export class Viewer2D {
|
||||
this._lwForced = null;
|
||||
this._lwDisplay = false;
|
||||
this._curLwPx = 0;
|
||||
this._lwScale = null; // null = LW_PX_PER_MM (setLineweightScale)
|
||||
SlugTextEngine.shared().catch(() => {}); // warm the font load; sprite fallback covers failure
|
||||
|
||||
this._scene = new THREE.Scene();
|
||||
@@ -1377,6 +1380,21 @@ export class Viewer2D {
|
||||
/** Whether lineweights are currently being drawn. */
|
||||
getLineweightEnabled() { return this._lwDisplay; }
|
||||
|
||||
/**
|
||||
* Display scale in screen pixels per mm of lineweight — AutoCAD's
|
||||
* "Adjust Display Scale" slider. Default 20 (1 px per 0.05 mm).
|
||||
* @param {number|null} pxPerMm null restores the default.
|
||||
*/
|
||||
setLineweightScale(pxPerMm) {
|
||||
this._lwScale = (pxPerMm > 0) ? pxPerMm : null;
|
||||
if (this._lastResult && !this._isLoading) {
|
||||
this.load(this._lastResult, { keepView: true, keepTheme: true, spaceHandle: this._activeSpaceHex });
|
||||
}
|
||||
}
|
||||
|
||||
/** Current lineweight display scale (px per mm). */
|
||||
getLineweightScale() { return this._lwScale || LW_PX_PER_MM; }
|
||||
|
||||
/** Track an entity-owned object so layer toggles can flip its visibility. */
|
||||
_addObj(obj, layer) {
|
||||
const key = layer ?? this._curLayer;
|
||||
@@ -2334,7 +2352,8 @@ export class Viewer2D {
|
||||
}
|
||||
const mm = raw === -3 ? LW_DEFAULT_MM : raw / 100;
|
||||
if (!(mm > LW_HAIRLINE_MM)) return 0;
|
||||
return Math.min(LW_MAX_PX, Math.round(mm * LW_PX_PER_MM * 10) / 10);
|
||||
const scale = this._lwScale || LW_PX_PER_MM;
|
||||
return Math.min(LW_MAX_PX, Math.round(mm * scale * 10) / 10);
|
||||
}
|
||||
|
||||
// Active-viewport VIEWTWIST (radians). The sheet is un-twisted by rotating the
|
||||
|
||||
Reference in New Issue
Block a user