"""Reading aids for the Ramp-A P1 drawings (read only): render a region, dump entities of a region. usage: python dxftools.py render x0 y0 x1 y1 [px] -> 판독/.png python dxftools.py dump x0 y0 x1 y1 [layer-regex] -> prints LINE/LWPOLYLINE/ARC/CIRCLE/TEXT DXF source: Code/RampA판독/dxf (converted from copies of RAG/Ramp-A교 P1 교각(1..4).dwg). """ import re import sys from pathlib import Path import ezdxf from ezdxf import bbox HERE = Path(__file__).resolve().parent DXF = HERE / "dxf" _CACHE = {} def doc(label): if label not in _CACHE: path = sorted(DXF.glob("*.dxf"))[int(label[1]) - 1] _CACHE[label] = ezdxf.readfile(path) return _CACHE[label] def in_region(e, x0, y0, x1, y1): try: b = bbox.extents([e], fast=True) except Exception: return False return b.has_data and b.extmax.x >= x0 and b.extmin.x <= x1 and b.extmax.y >= y0 and b.extmin.y <= y1 def entities(label, x0, y0, x1, y1, layer=None): rx = re.compile(layer) if layer else None for e in doc(label).modelspace(): if rx and not rx.search(e.dxf.layer): continue if in_region(e, x0, y0, x1, y1): yield e def describe(e): t, L, h = e.dxftype(), e.dxf.layer, e.dxf.handle r = lambda v: round(v, 1) if t == "LINE": s, f = e.dxf.start, e.dxf.end return f"{h} {L} LINE ({r(s.x)},{r(s.y)})-({r(f.x)},{r(f.y)}) len {r(s.distance(f))}" if t == "LWPOLYLINE": pts = [(r(p[0]), r(p[1])) for p in e.get_points()] return f"{h} {L} PLINE closed={e.closed} {pts}" if t == "ARC": c = e.dxf.center return f"{h} {L} ARC c({r(c.x)},{r(c.y)}) r {r(e.dxf.radius)} {r(e.dxf.start_angle)}..{r(e.dxf.end_angle)}" if t == "CIRCLE": c = e.dxf.center return f"{h} {L} CIRCLE c({r(c.x)},{r(c.y)}) r {r(e.dxf.radius)}" if t in ("TEXT", "MTEXT"): p = e.dxf.insert s = e.plain_text() if t == "MTEXT" else e.dxf.text return f"{h} {L} {t} ({r(p.x)},{r(p.y)}) '{s.strip()}'" if t == "INSERT": p = e.dxf.insert return f"{h} {L} INSERT {e.dxf.name} ({r(p.x)},{r(p.y)})" return f"{h} {L} {t}" def render(label, x0, y0, x1, y1, name, px=2400): import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt from ezdxf.addons.drawing import Frontend, RenderContext from ezdxf.addons.drawing.config import BackgroundPolicy, ColorPolicy, Configuration from ezdxf.addons.drawing.matplotlib import MatplotlibBackend d = doc(label) keep = list(entities(label, x0, y0, x1, y1)) fig = plt.figure(figsize=(px / 100, px * (y1 - y0) / (x1 - x0) / 100), dpi=100) ax = fig.add_axes([0, 0, 1, 1]) cfg = Configuration(background_policy=BackgroundPolicy.WHITE, color_policy=ColorPolicy.BLACK) Frontend(RenderContext(d), MatplotlibBackend(ax), config=cfg).draw_entities(keep) ax.set_xlim(x0, x1) ax.set_ylim(y0, y1) ax.set_aspect("equal") ax.axis("off") out = HERE / "판독" / f"{name}.png" out.parent.mkdir(exist_ok=True) fig.savefig(out, facecolor="white") plt.close(fig) return out if __name__ == "__main__": cmd, label = sys.argv[1], sys.argv[2] x0, y0, x1, y1 = map(float, sys.argv[3:7]) if cmd == "render": print(render(label, x0, y0, x1, y1, sys.argv[7], int(sys.argv[8]) if len(sys.argv) > 8 else 2400)) else: for e in entities(label, x0, y0, x1, y1, sys.argv[7] if len(sys.argv) > 7 else None): print(describe(e))