|
import gradio as gr |
|
import ezdxf |
|
import svgwrite |
|
import os |
|
import tempfile |
|
from pathlib import Path |
|
|
|
def dxf_to_svg_content(dxf_file_path): |
|
"""DXF νμΌμ SVG λ΄μ©μΌλ‘ λ³ν""" |
|
try: |
|
|
|
doc = ezdxf.readfile(dxf_file_path) |
|
msp = doc.modelspace() |
|
|
|
|
|
temp_svg = tempfile.NamedTemporaryFile(mode='w', suffix='.svg', delete=False) |
|
|
|
|
|
dwg = svgwrite.Drawing(temp_svg.name, size=('1000px', '1000px'), viewBox='0 0 1000 1000') |
|
|
|
|
|
entity_count = 0 |
|
for entity in msp: |
|
entity_count += 1 |
|
if entity.dxftype() == 'LINE': |
|
|
|
start = entity.dxf.start |
|
end = entity.dxf.end |
|
dwg.add(dwg.line( |
|
start=(start.x, start.y), |
|
end=(end.x, end.y), |
|
stroke='black', |
|
stroke_width=1, |
|
fill='none' |
|
)) |
|
|
|
elif entity.dxftype() == 'LWPOLYLINE': |
|
|
|
points = [] |
|
for point in entity.get_points(): |
|
points.append((point[0], point[1])) |
|
|
|
if len(points) > 1: |
|
polyline = dwg.polyline( |
|
points=points, |
|
stroke='black', |
|
stroke_width=1, |
|
fill='none' |
|
) |
|
|
|
|
|
if entity.closed: |
|
polyline.attribs['stroke-linejoin'] = 'round' |
|
|
|
dwg.add(polyline) |
|
|
|
elif entity.dxftype() == 'CIRCLE': |
|
|
|
center = entity.dxf.center |
|
radius = entity.dxf.radius |
|
dwg.add(dwg.circle( |
|
center=(center.x, center.y), |
|
r=radius, |
|
stroke='black', |
|
stroke_width=1, |
|
fill='none' |
|
)) |
|
|
|
elif entity.dxftype() == 'ARC': |
|
|
|
center = entity.dxf.center |
|
radius = entity.dxf.radius |
|
start_angle = entity.dxf.start_angle |
|
end_angle = entity.dxf.end_angle |
|
|
|
import math |
|
start_x = center.x + radius * math.cos(math.radians(start_angle)) |
|
start_y = center.y + radius * math.sin(math.radians(start_angle)) |
|
end_x = center.x + radius * math.cos(math.radians(end_angle)) |
|
end_y = center.y + radius * math.sin(math.radians(end_angle)) |
|
|
|
large_arc = 1 if abs(end_angle - start_angle) > 180 else 0 |
|
sweep = 1 if end_angle > start_angle else 0 |
|
|
|
path_data = f"M {start_x} {start_y} A {radius} {radius} 0 {large_arc} {sweep} {end_x} {end_y}" |
|
dwg.add(dwg.path( |
|
d=path_data, |
|
stroke='black', |
|
stroke_width=1, |
|
fill='none' |
|
)) |
|
|
|
|
|
dwg.save() |
|
|
|
return temp_svg.name, f"λ³ν μλ£! {entity_count}κ°μ μν°ν°λ₯Ό μ²λ¦¬νμ΅λλ€." |
|
|
|
except Exception as e: |
|
return None, f"λ³ν μ€ν¨: {str(e)}" |
|
|
|
def convert_multiple_dxf(dxf_files): |
|
"""μ¬λ¬ DXF νμΌμ κ°κ° λ³ννμ¬ κ°λ³ λ€μ΄λ‘λ κ°λ₯νκ² ν¨""" |
|
if not dxf_files: |
|
return [], "DXF νμΌλ€μ μ
λ‘λν΄μ£ΌμΈμ." |
|
|
|
try: |
|
converted_files = [] |
|
converted_count = 0 |
|
error_files = [] |
|
|
|
for dxf_file in dxf_files: |
|
try: |
|
svg_file, message = dxf_to_svg_content(dxf_file.name) |
|
if svg_file: |
|
|
|
original_name = Path(dxf_file.name).stem |
|
new_svg_path = f"{original_name}.svg" |
|
|
|
|
|
import shutil |
|
final_svg_path = os.path.join(tempfile.gettempdir(), f"converted_{original_name}.svg") |
|
shutil.copy2(svg_file, final_svg_path) |
|
|
|
converted_files.append(final_svg_path) |
|
converted_count += 1 |
|
|
|
|
|
os.unlink(svg_file) |
|
else: |
|
error_files.append(Path(dxf_file.name).name) |
|
except Exception as e: |
|
error_files.append(f"{Path(dxf_file.name).name} (μ€λ₯: {str(e)})") |
|
|
|
status_message = f"β
{converted_count}κ° νμΌμ΄ μ±κ³΅μ μΌλ‘ λ³νλμμ΅λλ€." |
|
if error_files: |
|
status_message += f"\nβ μ€ν¨ν νμΌλ€: {', '.join(error_files)}" |
|
|
|
return converted_files, status_message |
|
|
|
except Exception as e: |
|
return [], f"λ³ν μ€ν¨: {str(e)}" |
|
|
|
|
|
with gr.Blocks(title="DXF to SVG λ³νκΈ°") as demo: |
|
gr.Markdown("# DXF to SVG λ³νκΈ°") |
|
gr.Markdown("DXF νμΌλ€μ SVG νμμΌλ‘ λ³ννμ¬ κ°κ° λ€μ΄λ‘λν μ μμ΅λλ€.") |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
file_input = gr.File( |
|
label="DXF νμΌλ€ μ
λ‘λ", |
|
file_count="multiple", |
|
file_types=[".dxf"], |
|
type="filepath" |
|
) |
|
convert_btn = gr.Button("λ³ννκΈ°", variant="primary", size="lg") |
|
status_output = gr.Textbox(label="λ³ν μν", interactive=False, lines=3) |
|
|
|
with gr.Column(scale=2): |
|
gr.Markdown("### λ³νλ SVG νμΌλ€") |
|
gr.Markdown("λ³νμ΄ μλ£λλ©΄ μλμμ κ° νμΌμ κ°λ³μ μΌλ‘ λ€μ΄λ‘λν μ μμ΅λλ€.") |
|
|
|
|
|
file_outputs = [] |
|
for i in range(10): |
|
file_output = gr.File( |
|
label=f"λ³νλ νμΌ {i+1}", |
|
visible=False |
|
) |
|
file_outputs.append(file_output) |
|
|
|
def update_outputs(dxf_files): |
|
"""λ³ν κ²°κ³Όλ₯Ό κ°λ³ νμΌ μΆλ ₯μΌλ‘ μ
λ°μ΄νΈ""" |
|
converted_files, status = convert_multiple_dxf(dxf_files) |
|
|
|
|
|
outputs = [None] * 10 |
|
visibilities = [False] * 10 |
|
|
|
|
|
for i, file_path in enumerate(converted_files[:10]): |
|
outputs[i] = file_path |
|
visibilities[i] = True |
|
|
|
|
|
result = [status] |
|
for i in range(10): |
|
result.append(gr.File(value=outputs[i], visible=visibilities[i])) |
|
|
|
return result |
|
|
|
|
|
convert_btn.click( |
|
fn=update_outputs, |
|
inputs=[file_input], |
|
outputs=[status_output] + file_outputs |
|
) |
|
|
|
if __name__ == "__main__": |
|
demo.launch() |