Spaces:
Sleeping
Sleeping
| 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) | |