Spaces:
Running
Running
File size: 3,381 Bytes
4f55301 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 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",
) |