File size: 3,581 Bytes
5af6451
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import cadquery as cq
import os
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

# Function to analyze CAD file and generate G-code
def process_cad_and_generate_gcode(cad_file, feed_rate, spindle_speed):
    """
    Processes the uploaded CAD file, generates original G-code based on geometry, 
    and visualizes the 3D shape with toolpaths.
    """
    if not cad_file:
        return "No file provided. Please upload a valid CAD file.", None

    # Validate CAD file extension
    file_extension = os.path.splitext(cad_file.name)[1].lower()
    if file_extension not in [".step", ".stp", ".iges", ".igs"]:
        return "Unsupported file type. Please upload a STEP or IGES file.", None

    # Load the CAD file
    try:
        shape = cq.importers.importStep(cad_file.name)
    except Exception as e:
        return f"Error processing CAD file: {str(e)}", None

    # G-code generation logic based on bounding box
    gcode = []
    gcode.append("G21 ; Set units to millimeters")
    gcode.append("G90 ; Absolute positioning")
    gcode.append("G28 ; Move to home position")
    gcode.append(f"M3 S{spindle_speed} ; Start spindle")

    # Extract geometry information
    bounding_box = shape.val().BoundingBox()
    gcode.append(f"G00 X{bounding_box.xmin:.3f} Y{bounding_box.ymin:.3f} ; Rapid move to start")
    gcode.append(f"G01 Z-3.000 F{feed_rate} ; Move tool to cutting depth")
    gcode.append(f"G01 X{bounding_box.xmax:.3f} ; Linear cut along X axis")
    gcode.append(f"G01 Y{bounding_box.ymax:.3f} ; Linear cut along Y axis")
    gcode.append(f"G01 X{bounding_box.xmin:.3f} ; Return to X start position")
    gcode.append(f"G01 Y{bounding_box.ymin:.3f} ; Return to Y start position")
    gcode.append("G00 Z5.000 ; Retract tool")
    gcode.append("M5 ; Stop spindle")
    gcode.append("M30 ; End of program")

    # Visualization using Matplotlib
    fig = plt.figure()
    ax = fig.add_subplot(111, projection="3d")

    # Visualize the bounding box as a toolpath for demo purposes
    X = [bounding_box.xmin, bounding_box.xmax, bounding_box.xmax, bounding_box.xmin, bounding_box.xmin]
    Y = [bounding_box.ymin, bounding_box.ymin, bounding_box.ymax, bounding_box.ymax, bounding_box.ymin]
    Z = [bounding_box.zmin] * 5
    verts = [list(zip(X, Y, Z))]

    ax.add_collection3d(Poly3DCollection(verts, color="lightblue", linewidths=1, edgecolor="r"))
    ax.plot(X, Y, Z, color="red", linestyle="--", label="Toolpath")

    ax.set_xlabel("X Axis")
    ax.set_ylabel("Y Axis")
    ax.set_zlabel("Z Axis")
    ax.set_title("3D Visualization of CAD File with Toolpaths")

    # Save the visualization
    output_3d_image = "3d_visualization_with_toolpaths.png"
    plt.legend()
    plt.savefig(output_3d_image)
    plt.close()

    return "\n".join(gcode), output_3d_image

# Gradio Interface
iface = gr.Interface(
    fn=process_cad_and_generate_gcode,
    inputs=[
        gr.File(label="Upload CAD File (STEP, IGES)"),
        gr.Slider(50, 500, step=10, label="Feed Rate (mm/min)", value=100),
        gr.Slider(500, 5000, step=500, label="Spindle Speed (RPM)", value=1000),
    ],
    outputs=[
        gr.Textbox(label="Generated G-code"),
        gr.Image(label="3D Visualization with Toolpaths"),
    ],
    title="CAD to G-code Generator with Toolpaths Visualization",
    description="Upload a CAD file (STEP, IGES), and this tool generates CNC G-code based on the geometry, along with a toolpath visualization."
)

# Launch the Interface
if __name__ == "__main__":
    iface.launch(share=True)