@linkiez/dxf-renew 7.0.0 → 7.2.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/.eslintrc.json +1 -16
- package/.github/instructions/code-patterns.instructions.md +1 -1
- package/.github/instructions/exdxf.instruction.md +161 -0
- package/.github/instructions/tdd.instructions.md +271 -0
- package/.yarn/install-state.gz +0 -0
- package/ARCHITECTURE.md +163 -0
- package/CHANGELOG.md +39 -0
- package/CONTRIBUTING.md +16 -14
- package/README.md +113 -16
- package/{PLAN.md → ROADMAP.md} +244 -102
- package/dist/dxf.js +2212 -454
- package/docs/EZDXF_REFERENCE_SITEMAP.md +55 -0
- package/docs/FIXTURE_VALIDATION_EZDXF.md +62 -0
- package/lib/Helper.cjs +6 -2
- package/lib/Helper.cjs.map +3 -3
- package/lib/Helper.js +6 -2
- package/lib/Helper.js.map +2 -2
- package/lib/denormalise.cjs +131 -91
- package/lib/denormalise.cjs.map +2 -2
- package/lib/denormalise.js +131 -91
- package/lib/denormalise.js.map +2 -2
- package/lib/dimensionToSVG.cjs +318 -53
- package/lib/dimensionToSVG.cjs.map +3 -3
- package/lib/dimensionToSVG.js +316 -52
- package/lib/dimensionToSVG.js.map +2 -2
- package/lib/entityToPolyline.cjs +95 -0
- package/lib/entityToPolyline.cjs.map +3 -3
- package/lib/entityToPolyline.js +95 -0
- package/lib/entityToPolyline.js.map +2 -2
- package/lib/handlers/entities.cjs +111 -27
- package/lib/handlers/entities.cjs.map +3 -3
- package/lib/handlers/entities.js +111 -27
- package/lib/handlers/entities.js.map +3 -3
- package/lib/handlers/entity/dgnUnderlay.cjs +106 -0
- package/lib/handlers/entity/dgnUnderlay.cjs.map +7 -0
- package/lib/handlers/entity/dgnUnderlay.js +71 -0
- package/lib/handlers/entity/dgnUnderlay.js.map +7 -0
- package/lib/handlers/entity/dimension.cjs +24 -0
- package/lib/handlers/entity/dimension.cjs.map +2 -2
- package/lib/handlers/entity/dimension.js +24 -0
- package/lib/handlers/entity/dimension.js.map +2 -2
- package/lib/handlers/entity/dwfUnderlay.cjs +106 -0
- package/lib/handlers/entity/dwfUnderlay.cjs.map +7 -0
- package/lib/handlers/entity/dwfUnderlay.js +71 -0
- package/lib/handlers/entity/dwfUnderlay.js.map +7 -0
- package/lib/handlers/entity/image.cjs +123 -0
- package/lib/handlers/entity/image.cjs.map +7 -0
- package/lib/handlers/entity/image.js +88 -0
- package/lib/handlers/entity/image.js.map +7 -0
- package/lib/handlers/entity/leader.cjs +148 -0
- package/lib/handlers/entity/leader.cjs.map +7 -0
- package/lib/handlers/entity/leader.js +113 -0
- package/lib/handlers/entity/leader.js.map +7 -0
- package/lib/handlers/entity/mleader.cjs +69 -0
- package/lib/handlers/entity/mleader.cjs.map +7 -0
- package/lib/handlers/entity/mleader.js +34 -0
- package/lib/handlers/entity/mleader.js.map +7 -0
- package/lib/handlers/entity/mline.cjs +91 -0
- package/lib/handlers/entity/mline.cjs.map +7 -0
- package/lib/handlers/entity/mline.js +56 -0
- package/lib/handlers/entity/mline.js.map +7 -0
- package/lib/handlers/entity/oleframe.cjs +98 -0
- package/lib/handlers/entity/oleframe.cjs.map +7 -0
- package/lib/handlers/entity/oleframe.js +63 -0
- package/lib/handlers/entity/oleframe.js.map +7 -0
- package/lib/handlers/entity/pdfUnderlay.cjs +106 -0
- package/lib/handlers/entity/pdfUnderlay.cjs.map +7 -0
- package/lib/handlers/entity/pdfUnderlay.js +71 -0
- package/lib/handlers/entity/pdfUnderlay.js.map +7 -0
- package/lib/handlers/entity/ray.cjs +81 -0
- package/lib/handlers/entity/ray.cjs.map +7 -0
- package/lib/handlers/entity/ray.js +46 -0
- package/lib/handlers/entity/ray.js.map +7 -0
- package/lib/handlers/entity/region.cjs +67 -0
- package/lib/handlers/entity/region.cjs.map +7 -0
- package/lib/handlers/entity/region.js +32 -0
- package/lib/handlers/entity/region.js.map +7 -0
- package/lib/handlers/entity/shape.cjs +95 -0
- package/lib/handlers/entity/shape.cjs.map +7 -0
- package/lib/handlers/entity/shape.js +60 -0
- package/lib/handlers/entity/shape.js.map +7 -0
- package/lib/handlers/entity/table.cjs +71 -0
- package/lib/handlers/entity/table.cjs.map +7 -0
- package/lib/handlers/entity/table.js +36 -0
- package/lib/handlers/entity/table.js.map +7 -0
- package/lib/handlers/entity/tolerance.cjs +90 -0
- package/lib/handlers/entity/tolerance.cjs.map +7 -0
- package/lib/handlers/entity/tolerance.js +55 -0
- package/lib/handlers/entity/tolerance.js.map +7 -0
- package/lib/handlers/entity/trace.cjs +101 -0
- package/lib/handlers/entity/trace.cjs.map +7 -0
- package/lib/handlers/entity/trace.js +66 -0
- package/lib/handlers/entity/trace.js.map +7 -0
- package/lib/handlers/entity/wipeout.cjs +122 -0
- package/lib/handlers/entity/wipeout.cjs.map +7 -0
- package/lib/handlers/entity/wipeout.js +87 -0
- package/lib/handlers/entity/wipeout.js.map +7 -0
- package/lib/handlers/entity/xline.cjs +81 -0
- package/lib/handlers/entity/xline.cjs.map +7 -0
- package/lib/handlers/entity/xline.js +46 -0
- package/lib/handlers/entity/xline.js.map +7 -0
- package/lib/handlers/objects.cjs +299 -136
- package/lib/handlers/objects.cjs.map +2 -2
- package/lib/handlers/objects.js +299 -136
- package/lib/handlers/objects.js.map +2 -2
- package/lib/handlers/tables.cjs +96 -17
- package/lib/handlers/tables.cjs.map +2 -2
- package/lib/handlers/tables.js +96 -17
- package/lib/handlers/tables.js.map +2 -2
- package/lib/index.cjs +5 -2
- package/lib/index.cjs.map +3 -3
- package/lib/index.js +18 -16
- package/lib/index.js.map +3 -3
- package/lib/toJson.cjs +29 -0
- package/lib/toJson.cjs.map +7 -0
- package/lib/toJson.js +9 -0
- package/lib/toJson.js.map +7 -0
- package/lib/toSVG.cjs +105 -11
- package/lib/toSVG.cjs.map +3 -3
- package/lib/toSVG.js +106 -12
- package/lib/toSVG.js.map +2 -2
- package/lib/types/dimension-entity.cjs.map +1 -1
- package/lib/types/entity.cjs.map +1 -1
- package/lib/types/helper.cjs.map +1 -1
- package/lib/types/image-entity.cjs +17 -0
- package/lib/types/image-entity.cjs.map +7 -0
- package/lib/types/image-entity.js +1 -0
- package/lib/types/image-entity.js.map +7 -0
- package/lib/types/index.cjs +28 -0
- package/lib/types/index.cjs.map +2 -2
- package/lib/types/index.js +14 -0
- package/lib/types/index.js.map +2 -2
- package/lib/types/leader-entity.cjs +17 -0
- package/lib/types/leader-entity.cjs.map +7 -0
- package/lib/types/leader-entity.js +1 -0
- package/lib/types/leader-entity.js.map +7 -0
- package/lib/types/mleader-entity.cjs +17 -0
- package/lib/types/mleader-entity.cjs.map +7 -0
- package/lib/types/mleader-entity.js +1 -0
- package/lib/types/mleader-entity.js.map +7 -0
- package/lib/types/mline-entity.cjs +17 -0
- package/lib/types/mline-entity.cjs.map +7 -0
- package/lib/types/mline-entity.js +1 -0
- package/lib/types/mline-entity.js.map +7 -0
- package/lib/types/oleframe-entity.cjs +17 -0
- package/lib/types/oleframe-entity.cjs.map +7 -0
- package/lib/types/oleframe-entity.js +1 -0
- package/lib/types/oleframe-entity.js.map +7 -0
- package/lib/types/options.cjs.map +1 -1
- package/lib/types/ray-entity.cjs +17 -0
- package/lib/types/ray-entity.cjs.map +7 -0
- package/lib/types/ray-entity.js +1 -0
- package/lib/types/ray-entity.js.map +7 -0
- package/lib/types/region-entity.cjs +17 -0
- package/lib/types/region-entity.cjs.map +7 -0
- package/lib/types/region-entity.js +1 -0
- package/lib/types/region-entity.js.map +7 -0
- package/lib/types/shape-entity.cjs +17 -0
- package/lib/types/shape-entity.cjs.map +7 -0
- package/lib/types/shape-entity.js +1 -0
- package/lib/types/shape-entity.js.map +7 -0
- package/lib/types/table-entity.cjs +17 -0
- package/lib/types/table-entity.cjs.map +7 -0
- package/lib/types/table-entity.js +1 -0
- package/lib/types/table-entity.js.map +7 -0
- package/lib/types/tables.cjs.map +1 -1
- package/lib/types/tolerance-entity.cjs +17 -0
- package/lib/types/tolerance-entity.cjs.map +7 -0
- package/lib/types/tolerance-entity.js +1 -0
- package/lib/types/tolerance-entity.js.map +7 -0
- package/lib/types/trace-entity.cjs +17 -0
- package/lib/types/trace-entity.cjs.map +7 -0
- package/lib/types/trace-entity.js +1 -0
- package/lib/types/trace-entity.js.map +7 -0
- package/lib/types/underlay-entity.cjs +17 -0
- package/lib/types/underlay-entity.cjs.map +7 -0
- package/lib/types/underlay-entity.js +1 -0
- package/lib/types/underlay-entity.js.map +7 -0
- package/lib/types/wipeout-entity.cjs +17 -0
- package/lib/types/wipeout-entity.cjs.map +7 -0
- package/lib/types/wipeout-entity.js +1 -0
- package/lib/types/wipeout-entity.js.map +7 -0
- package/lib/types/xline-entity.cjs +17 -0
- package/lib/types/xline-entity.cjs.map +7 -0
- package/lib/types/xline-entity.js +1 -0
- package/lib/types/xline-entity.js.map +7 -0
- package/lib/util/escapeXmlText.cjs +27 -0
- package/lib/util/escapeXmlText.cjs.map +7 -0
- package/lib/util/escapeXmlText.js +7 -0
- package/lib/util/escapeXmlText.js.map +7 -0
- package/package.json +9 -18
- package/playwright.config.cjs +20 -0
- package/src/Helper.ts +8 -3
- package/src/denormalise.ts +182 -116
- package/src/dimensionToSVG.ts +466 -54
- package/src/entityToPolyline.ts +124 -2
- package/src/handlers/entities.ts +129 -34
- package/src/handlers/entity/dgnUnderlay.ts +94 -0
- package/src/handlers/entity/dimension.ts +27 -1
- package/src/handlers/entity/dwfUnderlay.ts +94 -0
- package/src/handlers/entity/image.ts +118 -0
- package/src/handlers/entity/leader.ts +153 -0
- package/src/handlers/entity/mleader.ts +46 -0
- package/src/handlers/entity/mline.ts +74 -0
- package/src/handlers/entity/oleframe.ts +62 -0
- package/src/handlers/entity/pdfUnderlay.ts +94 -0
- package/src/handlers/entity/ray.ts +52 -0
- package/src/handlers/entity/region.ts +42 -0
- package/src/handlers/entity/shape.ts +73 -0
- package/src/handlers/entity/table.ts +49 -0
- package/src/handlers/entity/tolerance.ts +75 -0
- package/src/handlers/entity/trace.ts +72 -0
- package/src/handlers/entity/wipeout.ts +114 -0
- package/src/handlers/entity/xline.ts +52 -0
- package/src/handlers/objects.ts +379 -139
- package/src/handlers/tables.ts +134 -21
- package/src/index.ts +9 -18
- package/src/toJson.ts +8 -0
- package/src/toSVG.ts +143 -10
- package/src/types/dimension-entity.ts +11 -0
- package/src/types/entity.ts +30 -0
- package/src/types/helper.ts +2 -1
- package/src/types/image-entity.ts +35 -0
- package/src/types/index.ts +14 -0
- package/src/types/leader-entity.ts +40 -0
- package/src/types/mleader-entity.ts +8 -0
- package/src/types/mline-entity.ts +12 -0
- package/src/types/oleframe-entity.ts +40 -0
- package/src/types/options.ts +48 -0
- package/src/types/ray-entity.ts +12 -0
- package/src/types/region-entity.ts +11 -0
- package/src/types/shape-entity.ts +19 -0
- package/src/types/table-entity.ts +14 -0
- package/src/types/tables.ts +160 -0
- package/src/types/tolerance-entity.ts +20 -0
- package/src/types/trace-entity.ts +14 -0
- package/src/types/underlay-entity.ts +35 -0
- package/src/types/wipeout-entity.ts +20 -0
- package/src/types/xline-entity.ts +12 -0
- package/src/util/escapeXmlText.ts +10 -0
- package/tools/browser_test_server.cjs +87 -0
- package/tools/ezdxf_generate_dimensions_all_types.py +246 -0
- package/tools/ezdxf_generate_dimensions_angular_3p.py +59 -0
- package/tools/ezdxf_generate_dimensions_large_scale.py +87 -0
- package/tools/ezdxf_regenerate_problem_fixtures.py +184 -0
- package/tools/ezdxf_validate_fixtures.py +165 -0
- package/docs/DIMENSION_SUMMARY.md +0 -248
- package/docs/DIMENSION_SUMMARY.pt-BR.md +0 -248
- package/docs/IMPLEMENTED-2D-ENTITIES.md +0 -54
- package/docs/IMPLEMENTED-2D-ENTITIES.pt-BR.md +0 -54
- package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.md +0 -241
- package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.pt-BR.md +0 -169
package/src/entityToPolyline.ts
CHANGED
|
@@ -9,8 +9,13 @@ import type {
|
|
|
9
9
|
EllipseEntity,
|
|
10
10
|
EntityToPolylineOptions,
|
|
11
11
|
HandlerVertex,
|
|
12
|
+
LeaderEntity,
|
|
12
13
|
LineEntity,
|
|
14
|
+
RayEntity,
|
|
15
|
+
ShapeEntity,
|
|
13
16
|
SplineEntity,
|
|
17
|
+
WipeoutEntity,
|
|
18
|
+
XLineEntity,
|
|
14
19
|
} from './types'
|
|
15
20
|
import type { PointTuple } from './types/common'
|
|
16
21
|
|
|
@@ -35,7 +40,17 @@ interface LocalPolylineEntity {
|
|
|
35
40
|
|
|
36
41
|
type Entity =
|
|
37
42
|
| LineEntity
|
|
43
|
+
| LeaderEntity
|
|
44
|
+
| RayEntity
|
|
45
|
+
| XLineEntity
|
|
46
|
+
| ShapeEntity
|
|
47
|
+
| WipeoutEntity
|
|
38
48
|
| (LocalPolylineEntity & { type: 'LWPOLYLINE' | 'POLYLINE' })
|
|
49
|
+
| {
|
|
50
|
+
type: 'SOLID' | 'TRACE'
|
|
51
|
+
corners?: Array<{ x: number; y: number }>
|
|
52
|
+
points?: Array<{ x: number; y: number }>
|
|
53
|
+
}
|
|
39
54
|
| CircleEntity
|
|
40
55
|
| EllipseEntity
|
|
41
56
|
| ArcEntity
|
|
@@ -151,7 +166,7 @@ export const interpolateBSpline = (
|
|
|
151
166
|
return polyline
|
|
152
167
|
}
|
|
153
168
|
|
|
154
|
-
export const polyfaceOutline = (entity: LocalPolylineEntity): Point[][] => {
|
|
169
|
+
export const polyfaceOutline = (entity: LocalPolylineEntity): Point[][] => { // NOSONAR
|
|
155
170
|
const vertices: Array<{ x: number; y: number }> = []
|
|
156
171
|
const faces: Array<{ indices: number[]; hiddens: boolean[] }> = []
|
|
157
172
|
|
|
@@ -219,13 +234,21 @@ export const polyfaceOutline = (entity: LocalPolylineEntity): Point[][] => {
|
|
|
219
234
|
* the DXF in SVG, Canvas, WebGL etc., without depending on native support
|
|
220
235
|
* of primitive objects (ellispe, spline etc.)
|
|
221
236
|
*/
|
|
222
|
-
export default function entityToPolyline(
|
|
237
|
+
export default function entityToPolyline( // NOSONAR
|
|
223
238
|
entity: Entity,
|
|
224
239
|
options?: EntityToPolylineOptions,
|
|
225
240
|
): Point[] {
|
|
226
241
|
options = options || {}
|
|
227
242
|
let polyline: Point[] | undefined
|
|
228
243
|
|
|
244
|
+
const INFINITE_LINE_LENGTH = 1000
|
|
245
|
+
|
|
246
|
+
const normalize2 = (x: number, y: number): { x: number; y: number } | null => {
|
|
247
|
+
const len = Math.hypot(x, y)
|
|
248
|
+
if (len === 0) return null
|
|
249
|
+
return { x: x / len, y: y / len }
|
|
250
|
+
}
|
|
251
|
+
|
|
229
252
|
if (entity.type === 'LINE') {
|
|
230
253
|
polyline = [
|
|
231
254
|
[entity.start.x, entity.start.y],
|
|
@@ -233,6 +256,92 @@ export default function entityToPolyline(
|
|
|
233
256
|
]
|
|
234
257
|
}
|
|
235
258
|
|
|
259
|
+
if (entity.type === 'LEADER') {
|
|
260
|
+
if (entity.vertices.length >= 2) {
|
|
261
|
+
polyline = entity.vertices.map((v) => [v.x, v.y])
|
|
262
|
+
} else {
|
|
263
|
+
logger.warn('LEADER entity with insufficient vertices')
|
|
264
|
+
polyline = []
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (entity.type === 'RAY') {
|
|
269
|
+
const dir = normalize2(entity.direction.x, entity.direction.y)
|
|
270
|
+
if (dir === null) {
|
|
271
|
+
logger.warn('RAY entity with zero direction vector')
|
|
272
|
+
polyline = []
|
|
273
|
+
} else {
|
|
274
|
+
polyline = [
|
|
275
|
+
[entity.start.x, entity.start.y],
|
|
276
|
+
[
|
|
277
|
+
entity.start.x + dir.x * INFINITE_LINE_LENGTH,
|
|
278
|
+
entity.start.y + dir.y * INFINITE_LINE_LENGTH,
|
|
279
|
+
],
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (entity.type === 'XLINE') {
|
|
285
|
+
const dir = normalize2(entity.direction.x, entity.direction.y)
|
|
286
|
+
if (dir === null) {
|
|
287
|
+
logger.warn('XLINE entity with zero direction vector')
|
|
288
|
+
polyline = []
|
|
289
|
+
} else {
|
|
290
|
+
polyline = [
|
|
291
|
+
[
|
|
292
|
+
entity.basePoint.x - dir.x * INFINITE_LINE_LENGTH,
|
|
293
|
+
entity.basePoint.y - dir.y * INFINITE_LINE_LENGTH,
|
|
294
|
+
],
|
|
295
|
+
[
|
|
296
|
+
entity.basePoint.x + dir.x * INFINITE_LINE_LENGTH,
|
|
297
|
+
entity.basePoint.y + dir.y * INFINITE_LINE_LENGTH,
|
|
298
|
+
],
|
|
299
|
+
]
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (entity.type === 'SHAPE') {
|
|
304
|
+
const x = entity.insertionPoint?.x ?? 0
|
|
305
|
+
const y = entity.insertionPoint?.y ?? 0
|
|
306
|
+
const size = entity.size ?? 0
|
|
307
|
+
const scaleX = entity.relativeXScale ?? 1
|
|
308
|
+
const length = size * scaleX
|
|
309
|
+
polyline = [
|
|
310
|
+
[x, y],
|
|
311
|
+
[x + length, y],
|
|
312
|
+
]
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (entity.type === 'WIPEOUT') {
|
|
316
|
+
const verts = entity.clipBoundaryVertices
|
|
317
|
+
if (!verts || verts.length < 2) {
|
|
318
|
+
logger.warn('WIPEOUT entity with missing clip boundary vertices')
|
|
319
|
+
polyline = []
|
|
320
|
+
} else {
|
|
321
|
+
const insX = entity.insertionPoint?.x ?? 0
|
|
322
|
+
const insY = entity.insertionPoint?.y ?? 0
|
|
323
|
+
|
|
324
|
+
const ux = entity.uVector?.x ?? 1
|
|
325
|
+
const uy = entity.uVector?.y ?? 0
|
|
326
|
+
|
|
327
|
+
const vx = entity.vVector?.x ?? 0
|
|
328
|
+
const vy = entity.vVector?.y ?? 1
|
|
329
|
+
|
|
330
|
+
polyline = verts.map((p) => [
|
|
331
|
+
insX + ux * p.x + vx * p.y,
|
|
332
|
+
insY + uy * p.x + vy * p.y,
|
|
333
|
+
])
|
|
334
|
+
|
|
335
|
+
if (polyline.length > 0) {
|
|
336
|
+
const first = polyline[0]
|
|
337
|
+
const last = polyline[polyline.length - 1]
|
|
338
|
+
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
339
|
+
polyline.push(first)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
236
345
|
if (entity.type === 'LWPOLYLINE' || entity.type === 'POLYLINE') {
|
|
237
346
|
polyline = []
|
|
238
347
|
if (entity.polyfaceMesh) {
|
|
@@ -330,6 +439,19 @@ export default function entityToPolyline(
|
|
|
330
439
|
)
|
|
331
440
|
}
|
|
332
441
|
|
|
442
|
+
if (entity.type === 'SOLID' || entity.type === 'TRACE') {
|
|
443
|
+
const corners = entity.corners ?? entity.points
|
|
444
|
+
if (corners && corners.length >= 4) {
|
|
445
|
+
polyline = [
|
|
446
|
+
[corners[0].x, corners[0].y],
|
|
447
|
+
[corners[1].x, corners[1].y],
|
|
448
|
+
[corners[2].x, corners[2].y],
|
|
449
|
+
[corners[3].x, corners[3].y],
|
|
450
|
+
[corners[0].x, corners[0].y],
|
|
451
|
+
]
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
333
455
|
if (!polyline) {
|
|
334
456
|
logger.warn('unsupported entity for converting to polyline:', entity.type)
|
|
335
457
|
return []
|
package/src/handlers/entities.ts
CHANGED
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
import type { DXFTuple } from '../types/dxf'
|
|
2
2
|
import type { Entity } from '../types/entity'
|
|
3
|
-
import type { PolylineEntity } from '../types/polyline-entity'
|
|
3
|
+
import type { PolylineEntity, Vertex } from '../types/polyline-entity'
|
|
4
4
|
|
|
5
5
|
import logger from '../util/logger'
|
|
6
6
|
import arc from './entity/arc'
|
|
7
7
|
import attdef from './entity/attdef'
|
|
8
8
|
import attrib from './entity/attrib'
|
|
9
9
|
import circle from './entity/circle'
|
|
10
|
+
import dgnUnderlay from './entity/dgnUnderlay'
|
|
10
11
|
import dimension from './entity/dimension'
|
|
12
|
+
import dwfUnderlay from './entity/dwfUnderlay'
|
|
11
13
|
import ellipse from './entity/ellipse'
|
|
12
14
|
import hatch from './entity/hatch'
|
|
15
|
+
import image from './entity/image'
|
|
13
16
|
import insert from './entity/insert'
|
|
17
|
+
import leader from './entity/leader'
|
|
14
18
|
import line from './entity/line'
|
|
15
19
|
import lwpolyline from './entity/lwpolyline'
|
|
20
|
+
import mleader from './entity/mleader'
|
|
21
|
+
import mline from './entity/mline'
|
|
16
22
|
import mtext from './entity/mtext'
|
|
17
23
|
import ole2Frame from './entity/ole2Frame'
|
|
24
|
+
import oleFrame from './entity/oleframe'
|
|
25
|
+
import pdfUnderlay from './entity/pdfUnderlay'
|
|
18
26
|
import point from './entity/point'
|
|
19
27
|
import polyline from './entity/polyline'
|
|
28
|
+
import ray from './entity/ray'
|
|
29
|
+
import region from './entity/region'
|
|
30
|
+
import shape from './entity/shape'
|
|
20
31
|
import solid from './entity/solid'
|
|
21
32
|
import spline from './entity/spline'
|
|
33
|
+
import table from './entity/table'
|
|
22
34
|
import text from './entity/text'
|
|
23
35
|
import threeDFace from './entity/threeDFace'
|
|
36
|
+
import tolerance from './entity/tolerance'
|
|
37
|
+
import trace from './entity/trace'
|
|
24
38
|
import vertex from './entity/vertex'
|
|
25
39
|
import viewport from './entity/viewport'
|
|
40
|
+
import wipeout from './entity/wipeout'
|
|
41
|
+
import xline from './entity/xline'
|
|
26
42
|
|
|
27
43
|
interface EntityHandler {
|
|
28
44
|
TYPE: string
|
|
@@ -33,15 +49,28 @@ const handlers: Record<string, EntityHandler> = [
|
|
|
33
49
|
point,
|
|
34
50
|
line,
|
|
35
51
|
lwpolyline,
|
|
52
|
+
mline,
|
|
53
|
+
mleader,
|
|
36
54
|
polyline,
|
|
37
55
|
vertex,
|
|
38
56
|
circle,
|
|
39
57
|
arc,
|
|
40
58
|
ellipse,
|
|
41
59
|
spline,
|
|
60
|
+
table,
|
|
42
61
|
solid,
|
|
62
|
+
trace,
|
|
43
63
|
hatch,
|
|
64
|
+
image,
|
|
65
|
+
leader,
|
|
66
|
+
ray,
|
|
67
|
+
region,
|
|
68
|
+
dwfUnderlay,
|
|
69
|
+
dgnUnderlay,
|
|
70
|
+
pdfUnderlay,
|
|
71
|
+
shape,
|
|
44
72
|
mtext,
|
|
73
|
+
tolerance,
|
|
45
74
|
attdef,
|
|
46
75
|
attrib,
|
|
47
76
|
text,
|
|
@@ -50,6 +79,9 @@ const handlers: Record<string, EntityHandler> = [
|
|
|
50
79
|
threeDFace,
|
|
51
80
|
viewport,
|
|
52
81
|
ole2Frame,
|
|
82
|
+
oleFrame,
|
|
83
|
+
xline,
|
|
84
|
+
wipeout,
|
|
53
85
|
].reduce((acc, mod) => {
|
|
54
86
|
acc[mod.TYPE] = mod
|
|
55
87
|
return acc
|
|
@@ -61,8 +93,102 @@ const handlers: Record<string, EntityHandler> = [
|
|
|
61
93
|
* @param tuples - Array of DXF tuples representing entities
|
|
62
94
|
* @returns Array of parsed entities
|
|
63
95
|
*/
|
|
96
|
+
class EntityGroupProcessor {
|
|
97
|
+
private readonly entities: Entity[] = []
|
|
98
|
+
private currentPolyline: PolylineEntity | undefined
|
|
99
|
+
|
|
100
|
+
getEntities(): Entity[] {
|
|
101
|
+
return this.entities
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
finalize(): void {
|
|
105
|
+
this.flushOpenPolyline('DXF ended with an open POLYLINE (missing SEQEND); flushing open polyline')
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
processGroup(tuples: DXFTuple[]): void {
|
|
109
|
+
const entityType = String(tuples[0][1])
|
|
110
|
+
const contentTuples = tuples.slice(1)
|
|
111
|
+
|
|
112
|
+
switch (entityType) {
|
|
113
|
+
case 'SEQEND':
|
|
114
|
+
this.endSequence()
|
|
115
|
+
break
|
|
116
|
+
case 'POLYLINE':
|
|
117
|
+
this.startPolyline(contentTuples)
|
|
118
|
+
break
|
|
119
|
+
case 'VERTEX':
|
|
120
|
+
this.addVertex(contentTuples)
|
|
121
|
+
break
|
|
122
|
+
default:
|
|
123
|
+
this.addEntity(entityType, contentTuples)
|
|
124
|
+
break
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private parseEntity(entityType: string, contentTuples: DXFTuple[]): Entity | undefined {
|
|
129
|
+
const handler = handlers[entityType]
|
|
130
|
+
if (!handler) {
|
|
131
|
+
logger.warn('unsupported type in ENTITIES section:', entityType)
|
|
132
|
+
return undefined
|
|
133
|
+
}
|
|
134
|
+
return handler.process(contentTuples)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private flushOpenPolyline(reason: string): void {
|
|
138
|
+
if (!this.currentPolyline) return
|
|
139
|
+
logger.warn(reason)
|
|
140
|
+
this.currentPolyline = undefined
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private endSequence(): void {
|
|
144
|
+
// SEQEND may also terminate other sequences (e.g. INSERT attributes).
|
|
145
|
+
// Only treat it as significant when we're inside a POLYLINE sequence.
|
|
146
|
+
this.currentPolyline = undefined
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private startPolyline(contentTuples: DXFTuple[]): void {
|
|
150
|
+
this.flushOpenPolyline(
|
|
151
|
+
'POLYLINE started while previous POLYLINE is still open; flushing previous polyline',
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
const e = this.parseEntity('POLYLINE', contentTuples)
|
|
155
|
+
if (!e) return
|
|
156
|
+
|
|
157
|
+
this.currentPolyline = e as PolylineEntity
|
|
158
|
+
this.entities.push(e)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private addVertex(contentTuples: DXFTuple[]): void {
|
|
162
|
+
const e = this.parseEntity('VERTEX', contentTuples)
|
|
163
|
+
if (!e) return
|
|
164
|
+
|
|
165
|
+
if (!this.currentPolyline) {
|
|
166
|
+
logger.error('ignoring invalid VERTEX entity')
|
|
167
|
+
return
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
this.currentPolyline.vertices.push(e as Vertex)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private addEntity(entityType: string, contentTuples: DXFTuple[]): void {
|
|
174
|
+
this.flushOpenPolyline('POLYLINE sequence ended without SEQEND; flushing open polyline')
|
|
175
|
+
|
|
176
|
+
const e = this.parseEntity(entityType, contentTuples)
|
|
177
|
+
if (!e) return
|
|
178
|
+
this.entities.push(e)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function processEntityGroups(entityGroups: DXFTuple[][]): Entity[] {
|
|
183
|
+
const processor = new EntityGroupProcessor()
|
|
184
|
+
for (const tuples of entityGroups) {
|
|
185
|
+
processor.processGroup(tuples)
|
|
186
|
+
}
|
|
187
|
+
processor.finalize()
|
|
188
|
+
return processor.getEntities()
|
|
189
|
+
}
|
|
190
|
+
|
|
64
191
|
export default function parseEntities(tuples: DXFTuple[]): Entity[] {
|
|
65
|
-
const entities: Entity[] = []
|
|
66
192
|
const entityGroups: DXFTuple[][] = []
|
|
67
193
|
let currentEntityTuples: DXFTuple[] = []
|
|
68
194
|
|
|
@@ -76,36 +202,5 @@ export default function parseEntities(tuples: DXFTuple[]): Entity[] {
|
|
|
76
202
|
currentEntityTuples.push(tuple)
|
|
77
203
|
}
|
|
78
204
|
|
|
79
|
-
|
|
80
|
-
for (const tuples of entityGroups) {
|
|
81
|
-
const entityType = tuples[0][1]
|
|
82
|
-
const contentTuples = tuples.slice(1)
|
|
83
|
-
|
|
84
|
-
if (entityType in handlers) {
|
|
85
|
-
const e = handlers[entityType].process(contentTuples)
|
|
86
|
-
// "POLYLINE" cannot be parsed in isolation, it is followed by
|
|
87
|
-
// N "VERTEX" entities and ended with a "SEQEND" entity.
|
|
88
|
-
// Essentially we convert POLYLINE to LWPOLYLINE - the extra
|
|
89
|
-
// vertex flags are not supported
|
|
90
|
-
if (entityType === 'POLYLINE') {
|
|
91
|
-
currentPolyline = e as PolylineEntity
|
|
92
|
-
entities.push(e)
|
|
93
|
-
} else if (entityType === 'VERTEX') {
|
|
94
|
-
if (currentPolyline) {
|
|
95
|
-
currentPolyline.vertices.push(e as any)
|
|
96
|
-
} else {
|
|
97
|
-
logger.error('ignoring invalid VERTEX entity')
|
|
98
|
-
}
|
|
99
|
-
} else if (entityType === 'SEQEND') {
|
|
100
|
-
currentPolyline = undefined
|
|
101
|
-
} else {
|
|
102
|
-
// All other entities
|
|
103
|
-
entities.push(e)
|
|
104
|
-
}
|
|
105
|
-
} else {
|
|
106
|
-
logger.warn('unsupported type in ENTITIES section:', entityType)
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return entities
|
|
205
|
+
return processEntityGroups(entityGroups)
|
|
111
206
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { DXFTuple } from '../../types'
|
|
2
|
+
|
|
3
|
+
import common from './common'
|
|
4
|
+
|
|
5
|
+
export const TYPE = 'DGNUNDERLAY'
|
|
6
|
+
|
|
7
|
+
interface UnderlayEntity {
|
|
8
|
+
type: typeof TYPE
|
|
9
|
+
|
|
10
|
+
insertionPoint: { x: number; y: number; z: number }
|
|
11
|
+
scale: { x: number; y: number; z: number }
|
|
12
|
+
normal: { x: number; y: number; z: number }
|
|
13
|
+
|
|
14
|
+
underlayDefinitionHandle?: string
|
|
15
|
+
rotation?: number
|
|
16
|
+
flags?: number
|
|
17
|
+
contrast?: number
|
|
18
|
+
fade?: number
|
|
19
|
+
|
|
20
|
+
[key: string]: unknown
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const process = (tuples: DXFTuple[]): UnderlayEntity => {
|
|
24
|
+
return tuples.reduce(
|
|
25
|
+
(entity, tuple) => {
|
|
26
|
+
const type = tuple[0]
|
|
27
|
+
const value = tuple[1]
|
|
28
|
+
|
|
29
|
+
switch (type) {
|
|
30
|
+
case 340:
|
|
31
|
+
entity.underlayDefinitionHandle = String(value)
|
|
32
|
+
break
|
|
33
|
+
|
|
34
|
+
case 10:
|
|
35
|
+
entity.insertionPoint.x = value as number
|
|
36
|
+
break
|
|
37
|
+
case 20:
|
|
38
|
+
entity.insertionPoint.y = value as number
|
|
39
|
+
break
|
|
40
|
+
case 30:
|
|
41
|
+
entity.insertionPoint.z = value as number
|
|
42
|
+
break
|
|
43
|
+
|
|
44
|
+
case 41:
|
|
45
|
+
entity.scale.x = value as number
|
|
46
|
+
break
|
|
47
|
+
case 42:
|
|
48
|
+
entity.scale.y = value as number
|
|
49
|
+
break
|
|
50
|
+
case 43:
|
|
51
|
+
entity.scale.z = value as number
|
|
52
|
+
break
|
|
53
|
+
|
|
54
|
+
case 50:
|
|
55
|
+
entity.rotation = value as number
|
|
56
|
+
break
|
|
57
|
+
|
|
58
|
+
case 210:
|
|
59
|
+
entity.normal.x = value as number
|
|
60
|
+
break
|
|
61
|
+
case 220:
|
|
62
|
+
entity.normal.y = value as number
|
|
63
|
+
break
|
|
64
|
+
case 230:
|
|
65
|
+
entity.normal.z = value as number
|
|
66
|
+
break
|
|
67
|
+
|
|
68
|
+
case 280:
|
|
69
|
+
entity.flags = value as number
|
|
70
|
+
break
|
|
71
|
+
case 281:
|
|
72
|
+
entity.contrast = value as number
|
|
73
|
+
break
|
|
74
|
+
case 282:
|
|
75
|
+
entity.fade = value as number
|
|
76
|
+
break
|
|
77
|
+
|
|
78
|
+
default:
|
|
79
|
+
Object.assign(entity, common(type, value))
|
|
80
|
+
break
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return entity
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: TYPE,
|
|
87
|
+
insertionPoint: { x: 0, y: 0, z: 0 },
|
|
88
|
+
scale: { x: 1, y: 1, z: 1 },
|
|
89
|
+
normal: { x: 0, y: 0, z: 1 },
|
|
90
|
+
} as UnderlayEntity,
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default { TYPE, process }
|
|
@@ -15,6 +15,8 @@ interface DimensionEntity {
|
|
|
15
15
|
type: typeof TYPE
|
|
16
16
|
block?: string
|
|
17
17
|
start: Point3D
|
|
18
|
+
angleVertex?: Point3D
|
|
19
|
+
arcPoint?: Point3D
|
|
18
20
|
textMidpoint: Point3D
|
|
19
21
|
measureStart: Point3D
|
|
20
22
|
measureEnd: Point3D
|
|
@@ -89,6 +91,30 @@ export const process = (tuples: DXFTuple[]): DimensionEntity => {
|
|
|
89
91
|
case 34:
|
|
90
92
|
entity.measureEnd.z = value as number
|
|
91
93
|
break
|
|
94
|
+
case 15:
|
|
95
|
+
entity.angleVertex = entity.angleVertex || { x: 0, y: 0, z: 0 }
|
|
96
|
+
entity.angleVertex.x = value as number
|
|
97
|
+
break
|
|
98
|
+
case 25:
|
|
99
|
+
entity.angleVertex = entity.angleVertex || { x: 0, y: 0, z: 0 }
|
|
100
|
+
entity.angleVertex.y = value as number
|
|
101
|
+
break
|
|
102
|
+
case 35:
|
|
103
|
+
entity.angleVertex = entity.angleVertex || { x: 0, y: 0, z: 0 }
|
|
104
|
+
entity.angleVertex.z = value as number
|
|
105
|
+
break
|
|
106
|
+
case 16:
|
|
107
|
+
entity.arcPoint = entity.arcPoint || { x: 0, y: 0, z: 0 }
|
|
108
|
+
entity.arcPoint.x = value as number
|
|
109
|
+
break
|
|
110
|
+
case 26:
|
|
111
|
+
entity.arcPoint = entity.arcPoint || { x: 0, y: 0, z: 0 }
|
|
112
|
+
entity.arcPoint.y = value as number
|
|
113
|
+
break
|
|
114
|
+
case 36:
|
|
115
|
+
entity.arcPoint = entity.arcPoint || { x: 0, y: 0, z: 0 }
|
|
116
|
+
entity.arcPoint.z = value as number
|
|
117
|
+
break
|
|
92
118
|
case 50:
|
|
93
119
|
entity.rotation = value as number
|
|
94
120
|
break
|
|
@@ -177,7 +203,7 @@ function parseBitCombinationsFromValue(value: number): BitCombinationsResult {
|
|
|
177
203
|
let ordinateType = false
|
|
178
204
|
let userDefinedLocation = false
|
|
179
205
|
|
|
180
|
-
//
|
|
206
|
+
// Note: keep this logic explicit; DXF stores flags as bit combinations.
|
|
181
207
|
if (value > 6) {
|
|
182
208
|
const alt1 = value - 32
|
|
183
209
|
const alt2 = value - 64
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { DXFTuple } from '../../types'
|
|
2
|
+
|
|
3
|
+
import common from './common'
|
|
4
|
+
|
|
5
|
+
export const TYPE = 'DWFUNDERLAY'
|
|
6
|
+
|
|
7
|
+
interface UnderlayEntity {
|
|
8
|
+
type: typeof TYPE
|
|
9
|
+
|
|
10
|
+
insertionPoint: { x: number; y: number; z: number }
|
|
11
|
+
scale: { x: number; y: number; z: number }
|
|
12
|
+
normal: { x: number; y: number; z: number }
|
|
13
|
+
|
|
14
|
+
underlayDefinitionHandle?: string
|
|
15
|
+
rotation?: number
|
|
16
|
+
flags?: number
|
|
17
|
+
contrast?: number
|
|
18
|
+
fade?: number
|
|
19
|
+
|
|
20
|
+
[key: string]: unknown
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const process = (tuples: DXFTuple[]): UnderlayEntity => {
|
|
24
|
+
return tuples.reduce(
|
|
25
|
+
(entity, tuple) => {
|
|
26
|
+
const type = tuple[0]
|
|
27
|
+
const value = tuple[1]
|
|
28
|
+
|
|
29
|
+
switch (type) {
|
|
30
|
+
case 340:
|
|
31
|
+
entity.underlayDefinitionHandle = String(value)
|
|
32
|
+
break
|
|
33
|
+
|
|
34
|
+
case 10:
|
|
35
|
+
entity.insertionPoint.x = value as number
|
|
36
|
+
break
|
|
37
|
+
case 20:
|
|
38
|
+
entity.insertionPoint.y = value as number
|
|
39
|
+
break
|
|
40
|
+
case 30:
|
|
41
|
+
entity.insertionPoint.z = value as number
|
|
42
|
+
break
|
|
43
|
+
|
|
44
|
+
case 41:
|
|
45
|
+
entity.scale.x = value as number
|
|
46
|
+
break
|
|
47
|
+
case 42:
|
|
48
|
+
entity.scale.y = value as number
|
|
49
|
+
break
|
|
50
|
+
case 43:
|
|
51
|
+
entity.scale.z = value as number
|
|
52
|
+
break
|
|
53
|
+
|
|
54
|
+
case 50:
|
|
55
|
+
entity.rotation = value as number
|
|
56
|
+
break
|
|
57
|
+
|
|
58
|
+
case 210:
|
|
59
|
+
entity.normal.x = value as number
|
|
60
|
+
break
|
|
61
|
+
case 220:
|
|
62
|
+
entity.normal.y = value as number
|
|
63
|
+
break
|
|
64
|
+
case 230:
|
|
65
|
+
entity.normal.z = value as number
|
|
66
|
+
break
|
|
67
|
+
|
|
68
|
+
case 280:
|
|
69
|
+
entity.flags = value as number
|
|
70
|
+
break
|
|
71
|
+
case 281:
|
|
72
|
+
entity.contrast = value as number
|
|
73
|
+
break
|
|
74
|
+
case 282:
|
|
75
|
+
entity.fade = value as number
|
|
76
|
+
break
|
|
77
|
+
|
|
78
|
+
default:
|
|
79
|
+
Object.assign(entity, common(type, value))
|
|
80
|
+
break
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return entity
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: TYPE,
|
|
87
|
+
insertionPoint: { x: 0, y: 0, z: 0 },
|
|
88
|
+
scale: { x: 1, y: 1, z: 1 },
|
|
89
|
+
normal: { x: 0, y: 0, z: 1 },
|
|
90
|
+
} as UnderlayEntity,
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default { TYPE, process }
|