@ifc-lite/drawing-2d 1.18.6 → 1.20.0
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 +23 -0
- package/dist/dxf/aci-colors.d.ts +17 -0
- package/dist/dxf/aci-colors.d.ts.map +1 -0
- package/dist/dxf/aci-colors.js +142 -0
- package/dist/dxf/aci-colors.js.map +1 -0
- package/dist/dxf/convert.d.ts +32 -0
- package/dist/dxf/convert.d.ts.map +1 -0
- package/dist/dxf/convert.js +382 -0
- package/dist/dxf/convert.js.map +1 -0
- package/dist/dxf/geom.d.ts +70 -0
- package/dist/dxf/geom.d.ts.map +1 -0
- package/dist/dxf/geom.js +194 -0
- package/dist/dxf/geom.js.map +1 -0
- package/dist/dxf/index.d.ts +13 -0
- package/dist/dxf/index.d.ts.map +1 -0
- package/dist/dxf/index.js +44 -0
- package/dist/dxf/index.js.map +1 -0
- package/dist/dxf/parser.d.ts +9 -0
- package/dist/dxf/parser.d.ts.map +1 -0
- package/dist/dxf/parser.js +903 -0
- package/dist/dxf/parser.js.map +1 -0
- package/dist/dxf/types.d.ts +255 -0
- package/dist/dxf/types.d.ts.map +1 -0
- package/dist/dxf/types.js +10 -0
- package/dist/dxf/types.js.map +1 -0
- package/dist/dxf/writer.d.ts +111 -0
- package/dist/dxf/writer.d.ts.map +1 -0
- package/dist/dxf/writer.js +338 -0
- package/dist/dxf/writer.js.map +1 -0
- package/dist/dxf-exporter.d.ts +66 -0
- package/dist/dxf-exporter.d.ts.map +1 -0
- package/dist/dxf-exporter.js +137 -0
- package/dist/dxf-exporter.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/svg-exporter.d.ts +23 -0
- package/dist/svg-exporter.d.ts.map +1 -1
- package/dist/svg-exporter.js +80 -1
- package/dist/svg-exporter.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -126,6 +126,29 @@ import {
|
|
|
126
126
|
|
|
127
127
|
Each renderer returns SVG fragments that you wrap in your own `<svg>` document — see the [2D Drawings Guide](https://ifclite.dev/docs/guide/drawing-2d/) for a worked sheet-composition example.
|
|
128
128
|
|
|
129
|
+
## DXF reference underlays
|
|
130
|
+
|
|
131
|
+
Import an existing DXF drawing (site plan, survey, coordination set) as a reference layer beneath a generated floor plan. `importDxf` parses ASCII DXF — `LINE`, `LWPOLYLINE`/`POLYLINE` (with bulge arcs), `CIRCLE`, `ARC`, `ELLIPSE`, `SPLINE`, `SOLID`/`TRACE`, `HATCH`, `TEXT`/`MTEXT`, `DIMENSION` blocks, and `INSERT`/`BLOCK` references — into world-plan geometry (metres, +Y = north; DXF and IFC are both Z-up) with per-layer visibility and resolved ACI/true colours and lineweights. `$INSUNITS` drives the unit conversion; unitless files with large extents are assumed to be millimetres (with a warning).
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import { importDxf, exportToSVG } from '@ifc-lite/drawing-2d';
|
|
135
|
+
|
|
136
|
+
const underlay = importDxf(dxfFileText, 'site-plan.dxf');
|
|
137
|
+
// underlay.layers[n].paths / .fills / .texts, underlay.bounds, underlay.warnings
|
|
138
|
+
|
|
139
|
+
// Composite beneath an exported floor plan:
|
|
140
|
+
const svg = exportToSVG(drawing, {
|
|
141
|
+
underlays: [{
|
|
142
|
+
underlay,
|
|
143
|
+
placement: { offsetX: 0, offsetY: 0, rotationDeg: 0, scale: 1 },
|
|
144
|
+
layerVisibility: { 'A-SITE': true },
|
|
145
|
+
opacity: 0.8,
|
|
146
|
+
}],
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Unsupported entity types are counted in `underlay.skipped` rather than failing the import; parse problems (missing blocks, spline approximations, unknown units) surface in `underlay.warnings`.
|
|
151
|
+
|
|
129
152
|
## API
|
|
130
153
|
|
|
131
154
|
See the [2D Drawings Guide](https://ifclite.dev/docs/guide/drawing-2d/) and [API Reference](https://ifclite.dev/docs/api/typescript/#ifc-litedrawing-2d).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare function rgbIntToCss(rgb: number): string;
|
|
2
|
+
/** Resolve an ACI colour number (1-255) to a CSS hex colour. */
|
|
3
|
+
export declare function aciToCss(index: number): string;
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a CSS colour (`#rrggbb`/`#rgb` hex, or an `rgb(...)`/`rgba(...)`
|
|
6
|
+
* function — the only formats {@link parseCssColor} handles; bare colour
|
|
7
|
+
* keywords are NOT parsed and take the ACI-7 fallback) to the nearest
|
|
8
|
+
* AutoCAD Color Index (1-255), for the DXF writer
|
|
9
|
+
* (issue #1861): DXF LAYER/entity colour is always an ACI, so an exported
|
|
10
|
+
* layer's CSS style colour needs a reverse lookup against the same table
|
|
11
|
+
* {@link aciToCss} reads forward. Ties break toward the lowest index (the
|
|
12
|
+
* classic 1-9 entries sort first, so a primary hue prefers its named ACI
|
|
13
|
+
* over a near-identical generated band entry). Unparseable input falls back
|
|
14
|
+
* to ACI 7 (black/white — the classic "on paper" colour).
|
|
15
|
+
*/
|
|
16
|
+
export declare function cssToAci(css: string): number;
|
|
17
|
+
//# sourceMappingURL=aci-colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aci-colors.d.ts","sourceRoot":"","sources":["../../src/dxf/aci-colors.ts"],"names":[],"mappings":"AA+DA,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,gEAAgE;AAChE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAqB5C"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* AutoCAD Color Index (ACI) → CSS colour.
|
|
6
|
+
*
|
|
7
|
+
* Indices 1-9 and 250-255 use the exact classic values. The 240 chromatic
|
|
8
|
+
* entries (10-249) are generated from the ACI band structure — 24 hue bands
|
|
9
|
+
* of 10 entries, alternating full/washed saturation over 5 brightness steps.
|
|
10
|
+
* That reproduces the classic table closely (visually indistinguishable for
|
|
11
|
+
* an underlay) without embedding 240 literals.
|
|
12
|
+
*
|
|
13
|
+
* ACI 7 is "white/black" (paper-dependent); the 2D canvas and SVG exports
|
|
14
|
+
* draw on white, so it maps to black.
|
|
15
|
+
*/
|
|
16
|
+
function hsvToRgbInt(hueDeg, s, v) {
|
|
17
|
+
const c = v * s;
|
|
18
|
+
const hp = (((hueDeg % 360) + 360) % 360) / 60;
|
|
19
|
+
const x = c * (1 - Math.abs((hp % 2) - 1));
|
|
20
|
+
let r = 0;
|
|
21
|
+
let g = 0;
|
|
22
|
+
let b = 0;
|
|
23
|
+
if (hp < 1)
|
|
24
|
+
[r, g, b] = [c, x, 0];
|
|
25
|
+
else if (hp < 2)
|
|
26
|
+
[r, g, b] = [x, c, 0];
|
|
27
|
+
else if (hp < 3)
|
|
28
|
+
[r, g, b] = [0, c, x];
|
|
29
|
+
else if (hp < 4)
|
|
30
|
+
[r, g, b] = [0, x, c];
|
|
31
|
+
else if (hp < 5)
|
|
32
|
+
[r, g, b] = [x, 0, c];
|
|
33
|
+
else
|
|
34
|
+
[r, g, b] = [c, 0, x];
|
|
35
|
+
const m = v - c;
|
|
36
|
+
const to255 = (f) => Math.round((f + m) * 255);
|
|
37
|
+
return (to255(r) << 16) | (to255(g) << 8) | to255(b);
|
|
38
|
+
}
|
|
39
|
+
function buildAciTable() {
|
|
40
|
+
const t = new Array(256).fill(0x000000);
|
|
41
|
+
t[1] = 0xff0000; // red
|
|
42
|
+
t[2] = 0xffff00; // yellow
|
|
43
|
+
t[3] = 0x00ff00; // green
|
|
44
|
+
t[4] = 0x00ffff; // cyan
|
|
45
|
+
t[5] = 0x0000ff; // blue
|
|
46
|
+
t[6] = 0xff00ff; // magenta
|
|
47
|
+
t[7] = 0x000000; // white/black → black on a white canvas
|
|
48
|
+
t[8] = 0x414141;
|
|
49
|
+
t[9] = 0x808080;
|
|
50
|
+
const brightness = [1.0, 0.8, 0.6, 0.5, 0.35];
|
|
51
|
+
for (let i = 10; i <= 249; i++) {
|
|
52
|
+
const c = i - 10;
|
|
53
|
+
const hue = Math.floor(c / 10) * 15;
|
|
54
|
+
const v = brightness[Math.floor((c % 10) / 2)];
|
|
55
|
+
const s = c % 2 === 1 ? 0.45 : 1.0;
|
|
56
|
+
t[i] = hsvToRgbInt(hue, s, v);
|
|
57
|
+
}
|
|
58
|
+
const grays = [0x333333, 0x505050, 0x696969, 0x828282, 0xbebebe, 0xffffff];
|
|
59
|
+
for (let i = 0; i < grays.length; i++)
|
|
60
|
+
t[250 + i] = grays[i];
|
|
61
|
+
return t;
|
|
62
|
+
}
|
|
63
|
+
const ACI_TABLE = buildAciTable();
|
|
64
|
+
export function rgbIntToCss(rgb) {
|
|
65
|
+
return `#${(rgb & 0xffffff).toString(16).padStart(6, '0')}`;
|
|
66
|
+
}
|
|
67
|
+
/** Resolve an ACI colour number (1-255) to a CSS hex colour. */
|
|
68
|
+
export function aciToCss(index) {
|
|
69
|
+
const i = Math.trunc(index);
|
|
70
|
+
if (i < 1 || i > 255 || !Number.isFinite(i))
|
|
71
|
+
return '#000000';
|
|
72
|
+
return rgbIntToCss(ACI_TABLE[i]);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Resolve a CSS colour (`#rrggbb`/`#rgb` hex, or an `rgb(...)`/`rgba(...)`
|
|
76
|
+
* function — the only formats {@link parseCssColor} handles; bare colour
|
|
77
|
+
* keywords are NOT parsed and take the ACI-7 fallback) to the nearest
|
|
78
|
+
* AutoCAD Color Index (1-255), for the DXF writer
|
|
79
|
+
* (issue #1861): DXF LAYER/entity colour is always an ACI, so an exported
|
|
80
|
+
* layer's CSS style colour needs a reverse lookup against the same table
|
|
81
|
+
* {@link aciToCss} reads forward. Ties break toward the lowest index (the
|
|
82
|
+
* classic 1-9 entries sort first, so a primary hue prefers its named ACI
|
|
83
|
+
* over a near-identical generated band entry). Unparseable input falls back
|
|
84
|
+
* to ACI 7 (black/white — the classic "on paper" colour).
|
|
85
|
+
*/
|
|
86
|
+
export function cssToAci(css) {
|
|
87
|
+
const rgb = parseCssColor(css);
|
|
88
|
+
if (rgb === null)
|
|
89
|
+
return 7;
|
|
90
|
+
const r = (rgb >> 16) & 0xff;
|
|
91
|
+
const g = (rgb >> 8) & 0xff;
|
|
92
|
+
const b = rgb & 0xff;
|
|
93
|
+
let best = 7;
|
|
94
|
+
let bestDist = Infinity;
|
|
95
|
+
for (let i = 1; i <= 255; i++) {
|
|
96
|
+
const c = ACI_TABLE[i];
|
|
97
|
+
const dr = r - ((c >> 16) & 0xff);
|
|
98
|
+
const dg = g - ((c >> 8) & 0xff);
|
|
99
|
+
const db = b - (c & 0xff);
|
|
100
|
+
const dist = dr * dr + dg * dg + db * db;
|
|
101
|
+
if (dist < bestDist) {
|
|
102
|
+
bestDist = dist;
|
|
103
|
+
best = i;
|
|
104
|
+
if (dist === 0)
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return best;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Parse `#rgb`, `#rrggbb`, `rgb(r,g,b)`, or `rgba(r,g,b,a)` into a 24-bit
|
|
112
|
+
* integer; null on failure. The function form is fully anchored (closing
|
|
113
|
+
* paren required, nothing before/after) and arity-checked — `rgb(...)` takes
|
|
114
|
+
* exactly three components and `rgba(...)` exactly four — so malformed
|
|
115
|
+
* strings (`rgb(1,2,3`, `rgb(1,2,3)junk`, `rgba(1,2,3)`) fall back to the
|
|
116
|
+
* caller's ACI-7 default instead of silently half-parsing (PR #1871 review).
|
|
117
|
+
*/
|
|
118
|
+
function parseCssColor(css) {
|
|
119
|
+
const s = css.trim();
|
|
120
|
+
const hex3 = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(s);
|
|
121
|
+
if (hex3) {
|
|
122
|
+
const r = parseInt(hex3[1] + hex3[1], 16);
|
|
123
|
+
const g = parseInt(hex3[2] + hex3[2], 16);
|
|
124
|
+
const b = parseInt(hex3[3] + hex3[3], 16);
|
|
125
|
+
return (r << 16) | (g << 8) | b;
|
|
126
|
+
}
|
|
127
|
+
const hex6 = /^#([0-9a-f]{6})$/i.exec(s);
|
|
128
|
+
if (hex6)
|
|
129
|
+
return parseInt(hex6[1], 16);
|
|
130
|
+
const rgbFn = /^(rgb|rgba)\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d*\.?\d+)\s*)?\)$/i.exec(s);
|
|
131
|
+
if (rgbFn) {
|
|
132
|
+
const hasAlpha = rgbFn[5] !== undefined;
|
|
133
|
+
if ((rgbFn[1].length === 3) === hasAlpha)
|
|
134
|
+
return null; // rgb: 3 args; rgba: 4 args
|
|
135
|
+
const r = Math.min(255, parseInt(rgbFn[2], 10));
|
|
136
|
+
const g = Math.min(255, parseInt(rgbFn[3], 10));
|
|
137
|
+
const b = Math.min(255, parseInt(rgbFn[4], 10));
|
|
138
|
+
return (r << 16) | (g << 8) | b;
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=aci-colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aci-colors.js","sourceRoot":"","sources":["../../src/dxf/aci-colors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a parsed DXF document into a reference underlay (issue #1782):
|
|
3
|
+
* tessellate entities, expand INSERT/DIMENSION blocks, resolve ACI/true
|
|
4
|
+
* colours per layer, and scale $INSUNITS to metres. Output is in WORLD
|
|
5
|
+
* plan coordinates (metres, +Y = north; DXF and IFC are both Z-up).
|
|
6
|
+
* Consumers map world → drawing space themselves — for a plan view that
|
|
7
|
+
* is `(x - shiftX, -(y - shiftY))` with the render-frame origin shift.
|
|
8
|
+
*/
|
|
9
|
+
import type { Point2D } from '../types.js';
|
|
10
|
+
import type { DxfDocument, DxfPlacement, DxfUnderlay } from './types.js';
|
|
11
|
+
export interface DxfConvertOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Override the unit conversion (drawing units → metres). When set, the
|
|
14
|
+
* file's $INSUNITS is ignored. Used by `importDxf`'s unitless-mm
|
|
15
|
+
* heuristic and available for callers that know the drawing's units.
|
|
16
|
+
*/
|
|
17
|
+
metersPerUnit?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Convert a parsed DXF document to a reference underlay.
|
|
21
|
+
* `name` labels the underlay (typically the file name).
|
|
22
|
+
*/
|
|
23
|
+
export declare function convertDxfToUnderlay(doc: DxfDocument, name?: string, options?: DxfConvertOptions): DxfUnderlay;
|
|
24
|
+
/**
|
|
25
|
+
* Apply a user placement to an underlay point in DRAWING space — i.e.
|
|
26
|
+
* after the world → drawing mapping (`x_d = x - shiftX`,
|
|
27
|
+
* `y_d = -(y - shiftY)` for a plan view). Rotation is counter-clockwise
|
|
28
|
+
* as seen on the plan (drawing space renders with +y downward on screen,
|
|
29
|
+
* hence the transposed rotation matrix).
|
|
30
|
+
*/
|
|
31
|
+
export declare function applyDxfPlacement(p: Point2D, placement: DxfPlacement): Point2D;
|
|
32
|
+
//# sourceMappingURL=convert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/dxf/convert.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAuB,MAAM,aAAa,CAAC;AAehE,OAAO,KAAK,EACV,WAAW,EAGX,YAAY,EACZ,WAAW,EAGZ,MAAM,YAAY,CAAC;AAqDpB,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,SAAQ,EAAE,OAAO,GAAE,iBAAsB,GAAG,WAAW,CA+DjH;AAmTD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,GAAG,OAAO,CAU9E"}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { aciToCss, rgbIntToCss } from './aci-colors.js';
|
|
5
|
+
import { expandBulgedVertices, matApply, matMultiply, matTRS, matTranslate, sampleArc, sampleCircle, sampleEllipse, tessellateSpline, MAT_IDENTITY, } from './geom.js';
|
|
6
|
+
/** $INSUNITS → metres. Unknown codes fall back to 1 with a warning. */
|
|
7
|
+
const INSUNITS_TO_METRES = {
|
|
8
|
+
0: 1, // unitless: assume metres (adjustable via placement scale)
|
|
9
|
+
1: 0.0254, // inches
|
|
10
|
+
2: 0.3048, // feet
|
|
11
|
+
3: 1609.344, // miles
|
|
12
|
+
4: 0.001, // millimetres
|
|
13
|
+
5: 0.01, // centimetres
|
|
14
|
+
6: 1, // metres
|
|
15
|
+
7: 1000, // kilometres
|
|
16
|
+
8: 2.54e-8, // microinches
|
|
17
|
+
9: 2.54e-5, // mils
|
|
18
|
+
10: 0.9144, // yards
|
|
19
|
+
11: 1e-10, // angstroms
|
|
20
|
+
12: 1e-9, // nanometres
|
|
21
|
+
13: 1e-6, // microns
|
|
22
|
+
14: 0.1, // decimetres
|
|
23
|
+
15: 10, // decametres
|
|
24
|
+
16: 100, // hectometres
|
|
25
|
+
};
|
|
26
|
+
/** Recursion guard for nested INSERTs. */
|
|
27
|
+
const MAX_BLOCK_DEPTH = 8;
|
|
28
|
+
/** Total block-instance expansion cap against pathological grids/nesting. */
|
|
29
|
+
const MAX_BLOCK_INSTANCES = 100_000;
|
|
30
|
+
const CONTINUOUS_LINETYPES = new Set(['', 'CONTINUOUS', 'BYLAYER', 'BYBLOCK']);
|
|
31
|
+
/**
|
|
32
|
+
* Convert a parsed DXF document to a reference underlay.
|
|
33
|
+
* `name` labels the underlay (typically the file name).
|
|
34
|
+
*/
|
|
35
|
+
export function convertDxfToUnderlay(doc, name = 'DXF', options = {}) {
|
|
36
|
+
const warnings = [...doc.warnings];
|
|
37
|
+
let unitScale;
|
|
38
|
+
if (options.metersPerUnit !== undefined && options.metersPerUnit > 0) {
|
|
39
|
+
unitScale = options.metersPerUnit;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const fromHeader = INSUNITS_TO_METRES[doc.insunits];
|
|
43
|
+
if (fromHeader === undefined) {
|
|
44
|
+
warnings.push(`Unknown $INSUNITS value ${doc.insunits}; drawing units treated as metres.`);
|
|
45
|
+
unitScale = 1;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
unitScale = fromHeader;
|
|
49
|
+
}
|
|
50
|
+
if (doc.insunits === 0) {
|
|
51
|
+
warnings.push('DXF has no $INSUNITS; drawing units treated as metres (adjust with the underlay scale).');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const state = {
|
|
55
|
+
doc,
|
|
56
|
+
unitScale,
|
|
57
|
+
layers: new Map(),
|
|
58
|
+
layerInfos: doc.layers,
|
|
59
|
+
bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity },
|
|
60
|
+
warnings,
|
|
61
|
+
instanceCount: 0,
|
|
62
|
+
instanceCapHit: false,
|
|
63
|
+
};
|
|
64
|
+
const ctx = {
|
|
65
|
+
m: MAT_IDENTITY,
|
|
66
|
+
byBlockColor: null,
|
|
67
|
+
insertLayer: null,
|
|
68
|
+
depth: 0,
|
|
69
|
+
stack: [],
|
|
70
|
+
};
|
|
71
|
+
emitEntities(doc.entities, ctx, state);
|
|
72
|
+
const bounds = Number.isFinite(state.bounds.minX)
|
|
73
|
+
? {
|
|
74
|
+
min: { x: state.bounds.minX, y: state.bounds.minY },
|
|
75
|
+
max: { x: state.bounds.maxX, y: state.bounds.maxY },
|
|
76
|
+
}
|
|
77
|
+
: { min: { x: 0, y: 0 }, max: { x: 0, y: 0 } };
|
|
78
|
+
// Stable layer order: DXF table order first, then referenced-only layers.
|
|
79
|
+
const ordered = [];
|
|
80
|
+
for (const layerName of doc.layers.keys()) {
|
|
81
|
+
const bucket = state.layers.get(layerName);
|
|
82
|
+
if (bucket)
|
|
83
|
+
ordered.push(bucket);
|
|
84
|
+
}
|
|
85
|
+
for (const [layerName, bucket] of state.layers) {
|
|
86
|
+
if (!doc.layers.has(layerName))
|
|
87
|
+
ordered.push(bucket);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
name,
|
|
91
|
+
layers: ordered.filter((l) => l.paths.length > 0 || l.fills.length > 0 || l.texts.length > 0),
|
|
92
|
+
bounds,
|
|
93
|
+
unitScale,
|
|
94
|
+
skipped: { ...doc.skipped },
|
|
95
|
+
warnings: state.warnings,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
99
|
+
// EMISSION
|
|
100
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
101
|
+
function getBucket(state, layerName) {
|
|
102
|
+
let bucket = state.layers.get(layerName);
|
|
103
|
+
if (!bucket) {
|
|
104
|
+
const info = state.layerInfos.get(layerName);
|
|
105
|
+
const color = info
|
|
106
|
+
? info.trueColor !== undefined
|
|
107
|
+
? rgbIntToCss(info.trueColor)
|
|
108
|
+
: aciToCss(info.colorNumber)
|
|
109
|
+
: '#000000';
|
|
110
|
+
bucket = {
|
|
111
|
+
name: layerName,
|
|
112
|
+
color,
|
|
113
|
+
visible: info ? info.visible : true,
|
|
114
|
+
paths: [],
|
|
115
|
+
fills: [],
|
|
116
|
+
texts: [],
|
|
117
|
+
};
|
|
118
|
+
state.layers.set(layerName, bucket);
|
|
119
|
+
}
|
|
120
|
+
return bucket;
|
|
121
|
+
}
|
|
122
|
+
/** Resolve an entity's CSS colour given its layer and BYBLOCK context. */
|
|
123
|
+
function resolveColor(entity, layerColor, ctx) {
|
|
124
|
+
if (entity.trueColor !== undefined)
|
|
125
|
+
return rgbIntToCss(entity.trueColor);
|
|
126
|
+
const cn = entity.colorNumber;
|
|
127
|
+
if (cn === 0)
|
|
128
|
+
return ctx.byBlockColor ?? layerColor; // BYBLOCK
|
|
129
|
+
if (cn >= 1 && cn <= 255)
|
|
130
|
+
return aciToCss(cn);
|
|
131
|
+
return layerColor; // BYLAYER (256) and anything unexpected
|
|
132
|
+
}
|
|
133
|
+
function isDashed(entity, layerInfo) {
|
|
134
|
+
const lt = (entity.linetype ?? '').trim().toUpperCase();
|
|
135
|
+
if (lt && lt !== 'BYLAYER') {
|
|
136
|
+
return lt !== 'CONTINUOUS' && lt !== 'BYBLOCK';
|
|
137
|
+
}
|
|
138
|
+
const layerLt = (layerInfo?.linetype ?? '').trim().toUpperCase();
|
|
139
|
+
return !CONTINUOUS_LINETYPES.has(layerLt);
|
|
140
|
+
}
|
|
141
|
+
/** Map a DXF-space point through the block chain into world metres. */
|
|
142
|
+
function toWorld(state, ctx, x, y) {
|
|
143
|
+
const p = matApply(ctx.m, x, y);
|
|
144
|
+
const wx = p.x * state.unitScale;
|
|
145
|
+
const wy = p.y * state.unitScale;
|
|
146
|
+
if (wx < state.bounds.minX)
|
|
147
|
+
state.bounds.minX = wx;
|
|
148
|
+
if (wx > state.bounds.maxX)
|
|
149
|
+
state.bounds.maxX = wx;
|
|
150
|
+
if (wy < state.bounds.minY)
|
|
151
|
+
state.bounds.minY = wy;
|
|
152
|
+
if (wy > state.bounds.maxY)
|
|
153
|
+
state.bounds.maxY = wy;
|
|
154
|
+
return { x: wx, y: wy };
|
|
155
|
+
}
|
|
156
|
+
/** Lineweight in mm: entity group 370, else the layer default. */
|
|
157
|
+
function resolveWidthMm(entity, layerInfo) {
|
|
158
|
+
return entity.lineweightMm ?? layerInfo?.lineweightMm;
|
|
159
|
+
}
|
|
160
|
+
function emitEntities(entities, ctx, state) {
|
|
161
|
+
for (const entity of entities) {
|
|
162
|
+
if (entity.invisible)
|
|
163
|
+
continue;
|
|
164
|
+
const effLayerName = entity.layer === '0' && ctx.insertLayer ? ctx.insertLayer : entity.layer;
|
|
165
|
+
const bucket = getBucket(state, effLayerName);
|
|
166
|
+
const layerInfo = state.layerInfos.get(effLayerName);
|
|
167
|
+
const color = resolveColor(entity, bucket.color, ctx);
|
|
168
|
+
const colorOverride = color !== bucket.color ? color : undefined;
|
|
169
|
+
const mirror = entity.extrusionZ < 0 ? -1 : 1;
|
|
170
|
+
const dashed = isDashed(entity, layerInfo) || undefined;
|
|
171
|
+
const widthMm = resolveWidthMm(entity, layerInfo);
|
|
172
|
+
const pushPath = (pts, closed) => {
|
|
173
|
+
if (pts.length < 2)
|
|
174
|
+
return;
|
|
175
|
+
bucket.paths.push({
|
|
176
|
+
points: pts.map((p) => toWorld(state, ctx, p.x * mirror, p.y)),
|
|
177
|
+
closed,
|
|
178
|
+
color: colorOverride,
|
|
179
|
+
dashed,
|
|
180
|
+
widthMm,
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
switch (entity.kind) {
|
|
184
|
+
case 'line':
|
|
185
|
+
// LINE coordinates are WCS; the OCS mirror does not apply.
|
|
186
|
+
bucket.paths.push({
|
|
187
|
+
points: [toWorld(state, ctx, entity.x1, entity.y1), toWorld(state, ctx, entity.x2, entity.y2)],
|
|
188
|
+
closed: false,
|
|
189
|
+
color: colorOverride,
|
|
190
|
+
dashed,
|
|
191
|
+
widthMm,
|
|
192
|
+
});
|
|
193
|
+
break;
|
|
194
|
+
case 'polyline':
|
|
195
|
+
pushPath(expandBulgedVertices(entity.vertices, entity.closed), entity.closed);
|
|
196
|
+
break;
|
|
197
|
+
case 'spline':
|
|
198
|
+
pushPath(tessellateSpline(entity.degree, entity.knots, entity.controlPoints, entity.fitPoints), entity.closed);
|
|
199
|
+
break;
|
|
200
|
+
case 'circle':
|
|
201
|
+
pushPath(sampleCircle(entity.cx, entity.cy, entity.r), true);
|
|
202
|
+
break;
|
|
203
|
+
case 'arc': {
|
|
204
|
+
// Mirrored OCS also mirrors angles: θ → 180° − θ.
|
|
205
|
+
const start = mirror < 0 ? 180 - entity.endDeg : entity.startDeg;
|
|
206
|
+
const end = mirror < 0 ? 180 - entity.startDeg : entity.endDeg;
|
|
207
|
+
const pts = sampleArc(entity.cx * mirror, entity.cy, entity.r, start, end);
|
|
208
|
+
if (pts.length >= 2) {
|
|
209
|
+
bucket.paths.push({
|
|
210
|
+
points: pts.map((p) => toWorld(state, ctx, p.x, p.y)),
|
|
211
|
+
closed: false,
|
|
212
|
+
color: colorOverride,
|
|
213
|
+
dashed,
|
|
214
|
+
widthMm,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
case 'solid': {
|
|
220
|
+
const ring = entity.corners.map((p) => toWorld(state, ctx, p.x * mirror, p.y));
|
|
221
|
+
if (ring.length >= 3) {
|
|
222
|
+
bucket.fills.push({ polygon: { outer: ring, holes: [] }, color: colorOverride, pattern: false });
|
|
223
|
+
}
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
case 'ellipse':
|
|
227
|
+
pushPath(sampleEllipse(entity.cx, entity.cy, entity.majorX, entity.majorY, entity.ratio, entity.startParam, entity.endParam), Math.abs(entity.endParam - entity.startParam) >= Math.PI * 2 - 1e-9);
|
|
228
|
+
break;
|
|
229
|
+
case 'hatch': {
|
|
230
|
+
if (entity.paths.length === 0)
|
|
231
|
+
break;
|
|
232
|
+
const rings = entity.paths
|
|
233
|
+
.map((path) => expandBulgedVertices(path.vertices, true).map((p) => toWorld(state, ctx, p.x * mirror, p.y)))
|
|
234
|
+
.filter((ring) => ring.length >= 3);
|
|
235
|
+
if (rings.length === 0)
|
|
236
|
+
break;
|
|
237
|
+
// Largest ring is the outer boundary; the rest render as holes.
|
|
238
|
+
let outerIdx = 0;
|
|
239
|
+
let outerArea = -1;
|
|
240
|
+
rings.forEach((ring, idx) => {
|
|
241
|
+
const area = Math.abs(ringArea(ring));
|
|
242
|
+
if (area > outerArea) {
|
|
243
|
+
outerArea = area;
|
|
244
|
+
outerIdx = idx;
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
const polygon = {
|
|
248
|
+
outer: rings[outerIdx],
|
|
249
|
+
holes: rings.filter((_, idx) => idx !== outerIdx),
|
|
250
|
+
};
|
|
251
|
+
bucket.fills.push({ polygon, color: colorOverride, pattern: !entity.solid });
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
case 'text': {
|
|
255
|
+
if (!entity.text.trim())
|
|
256
|
+
break;
|
|
257
|
+
const anchor = toWorld(state, ctx, entity.x * mirror, entity.y);
|
|
258
|
+
const rad = (entity.rotationDeg * Math.PI) / 180;
|
|
259
|
+
const tip = toWorld(state, ctx, (entity.x + Math.cos(rad)) * mirror, entity.y + Math.sin(rad));
|
|
260
|
+
let dirX = tip.x - anchor.x;
|
|
261
|
+
let dirY = tip.y - anchor.y;
|
|
262
|
+
const len = Math.hypot(dirX, dirY);
|
|
263
|
+
if (len > 1e-12) {
|
|
264
|
+
dirX /= len;
|
|
265
|
+
dirY /= len;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
dirX = 1;
|
|
269
|
+
dirY = 0;
|
|
270
|
+
}
|
|
271
|
+
const scaleEstimate = Math.sqrt(Math.abs(ctx.m[0] * ctx.m[3] - ctx.m[1] * ctx.m[2]));
|
|
272
|
+
const text = {
|
|
273
|
+
position: anchor,
|
|
274
|
+
text: entity.text,
|
|
275
|
+
height: entity.height * scaleEstimate * state.unitScale,
|
|
276
|
+
dirX,
|
|
277
|
+
dirY,
|
|
278
|
+
align: entity.hAlign,
|
|
279
|
+
valign: entity.vAlign,
|
|
280
|
+
color: colorOverride,
|
|
281
|
+
};
|
|
282
|
+
bucket.texts.push(text);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
case 'insert':
|
|
286
|
+
emitInsert(entity, ctx, state, effLayerName, color);
|
|
287
|
+
break;
|
|
288
|
+
case 'dimension': {
|
|
289
|
+
const block = entity.blockName ? state.doc.blocks.get(entity.blockName) : undefined;
|
|
290
|
+
if (!block) {
|
|
291
|
+
state.doc.skipped['DIMENSION'] = (state.doc.skipped['DIMENSION'] ?? 0) + 1;
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
if (ctx.depth >= MAX_BLOCK_DEPTH || ctx.stack.includes(block.name))
|
|
295
|
+
break;
|
|
296
|
+
// Dimension block geometry is already in the dimension's WCS.
|
|
297
|
+
emitEntities(block.entities, {
|
|
298
|
+
m: ctx.m,
|
|
299
|
+
byBlockColor: color,
|
|
300
|
+
insertLayer: effLayerName,
|
|
301
|
+
depth: ctx.depth + 1,
|
|
302
|
+
stack: [...ctx.stack, block.name],
|
|
303
|
+
}, state);
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function emitInsert(entity, ctx, state, effLayerName, resolvedColor) {
|
|
310
|
+
const block = state.doc.blocks.get(entity.blockName);
|
|
311
|
+
if (!block) {
|
|
312
|
+
state.warnings.push(`INSERT references missing block "${entity.blockName}".`);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (ctx.depth >= MAX_BLOCK_DEPTH) {
|
|
316
|
+
state.warnings.push(`Block nesting deeper than ${MAX_BLOCK_DEPTH} levels; "${entity.blockName}" truncated.`);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (ctx.stack.includes(entity.blockName)) {
|
|
320
|
+
state.warnings.push(`Recursive block reference "${entity.blockName}" skipped.`);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const mirror = entity.extrusionZ < 0 ? -1 : 1;
|
|
324
|
+
const cols = Math.min(entity.columnCount, 1024);
|
|
325
|
+
const rows = Math.min(entity.rowCount, 1024);
|
|
326
|
+
for (let row = 0; row < rows; row++) {
|
|
327
|
+
for (let col = 0; col < cols; col++) {
|
|
328
|
+
if (state.instanceCount >= MAX_BLOCK_INSTANCES) {
|
|
329
|
+
if (!state.instanceCapHit) {
|
|
330
|
+
state.instanceCapHit = true;
|
|
331
|
+
state.warnings.push(`Block instance limit (${MAX_BLOCK_INSTANCES}) reached; remaining inserts ignored.`);
|
|
332
|
+
}
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
state.instanceCount++;
|
|
336
|
+
// insert translation ∘ rotation ∘ scale ∘ grid offset ∘ base-point shift
|
|
337
|
+
let local = matTRS(entity.x * mirror, entity.y, mirror < 0 ? -entity.rotationDeg : entity.rotationDeg, entity.scaleX * mirror, entity.scaleY);
|
|
338
|
+
if (col !== 0 || row !== 0) {
|
|
339
|
+
local = matMultiply(local, matTranslate(col * entity.columnSpacing, row * entity.rowSpacing));
|
|
340
|
+
}
|
|
341
|
+
local = matMultiply(local, matTranslate(-block.baseX, -block.baseY));
|
|
342
|
+
emitEntities(block.entities, {
|
|
343
|
+
m: matMultiply(ctx.m, local),
|
|
344
|
+
byBlockColor: resolvedColor,
|
|
345
|
+
insertLayer: effLayerName,
|
|
346
|
+
depth: ctx.depth + 1,
|
|
347
|
+
stack: [...ctx.stack, entity.blockName],
|
|
348
|
+
}, state);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function ringArea(ring) {
|
|
353
|
+
let area = 0;
|
|
354
|
+
for (let i = 0; i < ring.length; i++) {
|
|
355
|
+
const a = ring[i];
|
|
356
|
+
const b = ring[(i + 1) % ring.length];
|
|
357
|
+
area += a.x * b.y - b.x * a.y;
|
|
358
|
+
}
|
|
359
|
+
return area / 2;
|
|
360
|
+
}
|
|
361
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
362
|
+
// PLACEMENT
|
|
363
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
364
|
+
/**
|
|
365
|
+
* Apply a user placement to an underlay point in DRAWING space — i.e.
|
|
366
|
+
* after the world → drawing mapping (`x_d = x - shiftX`,
|
|
367
|
+
* `y_d = -(y - shiftY)` for a plan view). Rotation is counter-clockwise
|
|
368
|
+
* as seen on the plan (drawing space renders with +y downward on screen,
|
|
369
|
+
* hence the transposed rotation matrix).
|
|
370
|
+
*/
|
|
371
|
+
export function applyDxfPlacement(p, placement) {
|
|
372
|
+
const rad = (placement.rotationDeg * Math.PI) / 180;
|
|
373
|
+
const c = Math.cos(rad);
|
|
374
|
+
const s = Math.sin(rad);
|
|
375
|
+
const x = p.x * placement.scale;
|
|
376
|
+
const y = p.y * placement.scale;
|
|
377
|
+
return {
|
|
378
|
+
x: x * c + y * s + placement.offsetX,
|
|
379
|
+
y: -x * s + y * c + placement.offsetY,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
//# sourceMappingURL=convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/dxf/convert.ts"],"names":[],"mappings":"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"}
|