File size: 3,405 Bytes
dd94919
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import tempfile, os
from raster_to_dxf import convert

def run_convert(image_path, upscale, denoise, threshold,
                min_branch, straight_tol, scale_mm,
                circularity, min_r_px):
    settings = {
        "upscale":            int(upscale),
        "denoise_h":          int(denoise),
        "threshold_value":    int(threshold),
        "min_branch_len":     int(min_branch),
        "straightness_tol":   float(straight_tol),
        "output_scale_mm":    float(scale_mm),
        "circle_circularity": float(circularity),
        "circle_min_r_px":    float(min_r_px),
    }
    out_path = tempfile.mktemp(suffix=".dxf")
    stats = convert(image_path, out_path, settings)
    summary = (f"✅  Lines: {stats['lines']}  |  "
               f"Polylines: {stats['polylines']}  |  "
               f"Circles: {stats['circles']}  |  "
               f"Arcs: {stats['arcs']}")
    return out_path, summary

with gr.Blocks(title="VectorForge v2 — PNG to DXF") as demo:
    gr.Markdown("""
# ⬡ VectorForge v2
### Clean centreline engineering drawing converter · PNG → DXF
Produces single-stroke geometry via skeleton graph tracing — not filled blobs.
    """)

    with gr.Row():
        with gr.Column():
            image_in = gr.Image(type="filepath", label="Upload PNG / JPG / BMP")

            gr.Markdown("### Pre-processing")
            upscale   = gr.Slider(1, 4,    value=3,    step=1,    label="Upscale factor (higher = better skeleton, slower)")
            denoise   = gr.Slider(1, 20,   value=8,    step=1,    label="Denoise strength")
            threshold = gr.Slider(100,254, value=200,  step=5,    label="Ink threshold (lower = pick up faint lines)")

            gr.Markdown("### Line geometry")
            min_branch  = gr.Slider(4, 50,  value=12,  step=2,   label="Min skeleton branch length (px) — raise to remove noise")
            straight_tol= gr.Slider(0.5,5,  value=1.5, step=0.5, label="Straightness tolerance (px) — raise to convert curves to lines")

            gr.Markdown("### Circle detection")
            circularity = gr.Slider(0.5, 1.0, value=0.72, step=0.02, label="Min circularity (0.72=loose, 0.90=strict circles only)")
            min_r_px    = gr.Slider(3, 50,    value=10,   step=1,    label="Min circle radius (upscaled px)")

            gr.Markdown("### Output")
            scale_mm = gr.Slider(0.01, 1.0, value=0.1, step=0.01, label="Scale (mm per source pixel)")

            btn = gr.Button("⚡ Convert to DXF", variant="primary")

        with gr.Column():
            dxf_out = gr.File(label="Download DXF")
            status  = gr.Textbox(label="Result stats", interactive=False)

            gr.Markdown("""
### Layer guide
| Layer | Contents |
|---|---|
| `GEOMETRY` | All straight lines and polylines |
| `CIRCLES` | Detected circular elements |
| `ARCS` | Curved arc segments |

### Recommended settings by drawing type
| Drawing type | Upscale | Min branch | Straight tol |
|---|---|---|---|
| Clean CAD scan | 3 | 12 | 1.5 |
| Photo / skewed | 3 | 20 | 2.5 |
| Dense schematic | 2 | 8  | 1.0 |
| Faint/old print | 4 | 16 | 2.0 |
            """)

    btn.click(
        run_convert,
        inputs=[image_in, upscale, denoise, threshold,
                min_branch, straight_tol, scale_mm,
                circularity, min_r_px],
        outputs=[dxf_out, status]
    )

demo.launch()