From 3792248cd1d9bc90f1ae2102c5a87bfc17160a65 Mon Sep 17 00:00:00 2001 From: jan Date: Mon, 9 Mar 2026 11:16:30 -0700 Subject: [PATCH] [dxf] improve dxf reader (ezdxf 1.4 related LWPolyLine changes) --- masque/file/dxf.py | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/masque/file/dxf.py b/masque/file/dxf.py index 962d41d..db01f51 100644 --- a/masque/file/dxf.py +++ b/masque/file/dxf.py @@ -218,28 +218,36 @@ def _read_block(block: ezdxf.layouts.BlockLayout | ezdxf.layouts.Modelspace) -> layer = attr.get('layer', DEFAULT_LAYER) width = 0 - if points.shape[1] > 2: - if (points[0, 2] != points[:, 2]).any(): - raise PatternError('PolyLine has non-constant width (not yet representable in masque!)') - if points.shape[1] == 4 and (points[:, 3] != 0).any(): - raise PatternError('LWPolyLine has bulge (not yet representable in masque!)') + if isinstance(element, LWPolyline): + # ezdxf 1.4+ get_points() returns (x, y, start_width, end_width, bulge) + if points.shape[1] >= 5: + if (points[:, 4] != 0).any(): + raise PatternError('LWPolyline has bulge (not yet representable in masque!)') + if (points[:, 2] != points[:, 3]).any() or (points[:, 2] != points[0, 2]).any(): + raise PatternError('LWPolyline has non-constant width (not yet representable in masque!)') + width = points[0, 2] + elif points.shape[1] == 3: + # width used to be in column 2 + width = points[0, 2] - width = points[0, 2] - if width == 0: - width = attr.get('const_width', 0) + if width == 0: + width = attr.get('const_width', 0) is_closed = element.closed - # If the last point is a repeat of the first, drop it. - if len(points) > 1 and numpy.allclose(points[0, :2], points[-1, :2]): - verts = points[:-1, :2] - else: - verts = points[:, :2] + verts = points[:, :2] + if is_closed and (len(verts) < 2 or not numpy.allclose(verts[0], verts[-1])): + verts = numpy.vstack((verts, verts[0])) shape: Path | Polygon - if width == 0 and is_closed and len(verts) >= 3: - shape = Polygon(vertices=verts) + if width == 0 and is_closed: + # Use Polygon if it has at least 3 unique vertices + shape_verts = verts[:-1] if len(verts) > 1 else verts + if len(shape_verts) >= 3: + shape = Polygon(vertices=shape_verts) + else: + shape = Path(width=width, vertices=verts) else: - shape = Path(width=width, vertices=points[:, :2]) + shape = Path(width=width, vertices=verts) pat.shapes[layer].append(shape) elif isinstance(element, Solid | Trace):