Spaces:
Running
Running
| import math | |
| import ezdxf | |
| import matplotlib.pyplot as plt | |
| from matplotlib.patches import Circle, Arc | |
| def render_dxf_layer_to_png( | |
| doc: object, | |
| layer_name: str, | |
| output_path: str = "layer.png", | |
| dpi: int = 300, | |
| line_width: float = 1.0, | |
| padding_ratio: float = 0.05, | |
| ): | |
| msp = doc.modelspace() | |
| fig, ax = plt.subplots() | |
| xs = [] | |
| ys = [] | |
| def update_bounds(x, y): | |
| xs.append(x) | |
| ys.append(y) | |
| for e in msp: | |
| if e.dxf.layer != layer_name: | |
| continue | |
| etype = e.dxftype() | |
| if etype == "LINE": | |
| x1, y1 = e.dxf.start.x, e.dxf.start.y | |
| x2, y2 = e.dxf.end.x, e.dxf.end.y | |
| ax.plot([x1, x2], [y1, y2], linewidth=line_width) | |
| update_bounds(x1, y1) | |
| update_bounds(x2, y2) | |
| elif etype == "LWPOLYLINE": | |
| pts = [(p[0], p[1]) for p in e.get_points()] | |
| if len(pts) >= 2: | |
| x = [p[0] for p in pts] | |
| y = [p[1] for p in pts] | |
| if e.closed: | |
| x.append(pts[0][0]) | |
| y.append(pts[0][1]) | |
| ax.plot(x, y, linewidth=line_width) | |
| for px, py in pts: | |
| update_bounds(px, py) | |
| elif etype == "POLYLINE": | |
| pts = [(v.dxf.location.x, v.dxf.location.y) for v in e.vertices] | |
| if len(pts) >= 2: | |
| x = [p[0] for p in pts] | |
| y = [p[1] for p in pts] | |
| if e.is_closed: | |
| x.append(pts[0][0]) | |
| y.append(pts[0][1]) | |
| ax.plot(x, y, linewidth=line_width) | |
| for px, py in pts: | |
| update_bounds(px, py) | |
| elif etype == "CIRCLE": | |
| cx, cy = e.dxf.center.x, e.dxf.center.y | |
| r = e.dxf.radius | |
| patch = Circle((cx, cy), r, fill=False, linewidth=line_width) | |
| ax.add_patch(patch) | |
| update_bounds(cx - r, cy - r) | |
| update_bounds(cx + r, cy + r) | |
| elif etype == "ARC": | |
| cx, cy = e.dxf.center.x, e.dxf.center.y | |
| r = e.dxf.radius | |
| start_angle = e.dxf.start_angle | |
| end_angle = e.dxf.end_angle | |
| patch = Arc( | |
| (cx, cy), | |
| width=2 * r, | |
| height=2 * r, | |
| angle=0, | |
| theta1=start_angle, | |
| theta2=end_angle, | |
| linewidth=line_width, | |
| ) | |
| ax.add_patch(patch) | |
| # γγ¦γ³γγ£γ³γ°ζ΄ζ°γ―η°‘ζηγ«εε ¨δ½γ§εγ | |
| update_bounds(cx - r, cy - r) | |
| update_bounds(cx + r, cy + r) | |
| if not xs or not ys: | |
| raise ValueError(f"Layer '{layer_name}' γ«ζη»ε―Ύθ±‘γγγγΎγγ") | |
| min_x, max_x = min(xs), max(xs) | |
| min_y, max_y = min(ys), max(ys) | |
| dx = max_x - min_x | |
| dy = max_y - min_y | |
| pad_x = max(dx * padding_ratio, 1e-6) | |
| pad_y = max(dy * padding_ratio, 1e-6) | |
| ax.set_xlim(min_x - pad_x, max_x + pad_x) | |
| ax.set_ylim(min_y - pad_y, max_y + pad_y) | |
| ax.set_aspect("equal", adjustable="box") | |
| ax.axis("off") | |
| plt.savefig(output_path, dpi=dpi, bbox_inches="tight", pad_inches=0) | |
| plt.close(fig) | |
| if __name__ == "__main__": | |
| render_dxf_layer_to_png( | |
| dxf_path="input.dxf", | |
| layer_name="MY_LAYER", | |
| output_path="layer.png", | |
| ) |