Feb-17-2024, 11:57 AM
import tkinter as tk from tkinter import ttk, messagebox from reportlab.pdfgen import canvas class GuillotineCuttingOptimizer: def __init__(self, stock_width, stock_length, stock_quantity, cut_sizes): self.stock_width = stock_width self.stock_length = stock_length self.stock_quantity = stock_quantity self.cut_sizes = cut_sizes self.sheets_needed = 0 self.remaining_stock_area = 0 self.cut_plan = [] def optimize_cutting_plan(self): self.cut_sizes.sort(key=lambda x: x[0] * x[1], reverse=True) stock_area = self.stock_width * self.stock_length * self.stock_quantity remaining_stock_area = stock_area sheets_needed = 0 cut_plan = [] while self.cut_sizes: sheet_area = stock_area current_cut_plan = [] while self.cut_sizes: cut_width, cut_length, cut_quantity = self.cut_sizes.pop(0) if cut_width <= self.stock_width and cut_length <= self.stock_length: current_cut_plan.append((cut_width, cut_length, cut_quantity)) sheet_area -= cut_width * cut_length * cut_quantity if sheet_area < stock_area: sheets_needed += 1 remaining_stock_area -= sheet_area cut_plan.extend(current_cut_plan) self.sheets_needed = sheets_needed self.remaining_stock_area = remaining_stock_area self.cut_plan = cut_plan class GuillotineApp: def __init__(self, root): self.root = root self.root.title("Guillotine Cutting Planner") # Variables self.stock_width_var = tk.DoubleVar() self.stock_length_var = tk.DoubleVar() self.stock_quantity_var = tk.IntVar() self.cut_width_var = tk.DoubleVar() self.cut_length_var = tk.DoubleVar() self.cut_quantity_var = tk.IntVar() self.cut_sizes = [] # Create and place widgets self.create_widgets() def create_widgets(self): # Stock Sheet Entry stock_frame = ttk.LabelFrame(self.root, text="Stock Sheet") stock_frame.grid(row=0, column=0, padx=10, pady=10, sticky="ew") self.create_label_entry(stock_frame, "Width:", self.stock_width_var, 0) self.create_label_entry(stock_frame, "Length:", self.stock_length_var, 1) self.create_label_entry(stock_frame, "Quantity:", self.stock_quantity_var, 2) # Cut Sizes Entry cuts_frame = ttk.LabelFrame(self.root, text="Cut Sizes") cuts_frame.grid(row=1, column=0, padx=10, pady=10, sticky="ew") self.create_label_entry(cuts_frame, "Width:", self.cut_width_var, 0) self.create_label_entry(cuts_frame, "Length:", self.cut_length_var, 1) self.create_label_entry(cuts_frame, "Quantity:", self.cut_quantity_var, 2) ttk.Button(self.root, text="Optimize", command=self.optimize_and_display).grid(row=2, column=0, pady=20) ttk.Button(self.root, text="Export to PDF", command=self.export_to_pdf).grid(row=3, column=0, pady=10) # Canvas for Drawing self.canvas = tk.Canvas(self.root, bg="white", width=800, height=600) self.canvas.grid(row=0, column=1, rowspan=4, padx=10, pady=10, sticky="nsew") # Make canvas resizable self.root.grid_rowconfigure(0, weight=1) self.root.grid_columnconfigure(1, weight=1) # Bind canvas resize event self.canvas.bind("<Configure>", self.on_canvas_resize) def create_label_entry(self, frame, label_text, variable, row): ttk.Label(frame, text=label_text).grid(row=row, column=0, padx=5, pady=5, sticky="e") ttk.Entry(frame, textvariable=variable).grid(row=row, column=1, padx=5, pady=5, sticky="w") def on_canvas_resize(self, event): # Redraw the cut sizes when the canvas is resized self.display_cut_sizes(self.cut_sizes) def optimize_and_display(self): try: stock_width = float(self.stock_width_var.get()) stock_length = float(self.stock_length_var.get()) stock_quantity = int(self.stock_quantity_var.get()) cut_width = float(self.cut_width_var.get()) cut_length = float(self.cut_length_var.get()) cut_quantity = int(self.cut_quantity_var.get()) if cut_width > 0 and cut_length > 0 and cut_quantity > 0: self.cut_sizes.append((cut_width, cut_length, cut_quantity)) else: messagebox.showerror("Error", "Please enter valid positive values for Cut Width, Length, and Quantity.") optimizer = GuillotineCuttingOptimizer(stock_width, stock_length, stock_quantity, self.cut_sizes) optimizer.optimize_cutting_plan() self.display_stock_size(stock_width, stock_length, stock_quantity) self.display_optimization_results(optimizer) self.display_cut_sizes(optimizer.cut_plan) messagebox.showinfo("Optimized Calculation", f"Optimized Cutting Plan:\nTotal sheets needed: {optimizer.sheets_needed}\nRemaining stock area: {optimizer.remaining_stock_area:.2f} mm²") except ValueError: messagebox.showerror("Error", "Please enter valid numeric values.") def display_stock_size(self, stock_width, stock_length, stock_quantity): # Clear previous drawings on the canvas self.canvas.delete("stock_size") # Calculate total dimensions of stock sheet total_width = stock_width * stock_quantity total_length = stock_length # Draw the stock sheet rectangle self.canvas.create_rectangle(10, 10, total_width + 10, total_length + 10, outline="black", fill="lightgreen", tags="stock_size") # Display stock size dimensions self.canvas.create_text(total_width / 2 + 10, total_length / 2 + 10, text=f"Stock Size\n{stock_width} mm x {stock_length} mm x {stock_quantity}", fill="black", anchor="center", tags="stock_size") def display_cut_sizes(self, cut_plan): # Clear previous drawings on the canvas self.canvas.delete("cut_sizes") # Calculate total dimensions of stock sheet and cut sizes total_width = max(self.stock_width_var.get(), *map(lambda x: x[0], cut_plan)) total_length = max(self.stock_length_var.get(), *map(lambda x: x[1], cut_plan)) # Calculate scale factor based on canvas size and total dimensions scale_factor = min(self.canvas.winfo_width() / total_width, self.canvas.winfo_height() / total_length) current_x = 10 current_y = 10 for cut_width, cut_length, cut_quantity in cut_plan: # Scale dimensions for better visibility scaled_width = cut_width * scale_factor scaled_length = cut_length * scale_factor # Draw the cut size rectangle for _ in range(cut_quantity): self.canvas.create_rectangle(current_x, current_y, current_x + scaled_width, current_y + scaled_length, outline="black", fill="lightblue", tags="cut_sizes") # Display cut size dimensions self.canvas.create_text(current_x + scaled_width / 2, current_y - 5, text=f"{cut_width} mm", fill="black", anchor="s", tags="cut_sizes") self.canvas.create_text(current_x - 5, current_y + scaled_length / 2, text=f"{cut_length} mm", fill="black", anchor="e", tags="cut_sizes") # Display cut size quantity self.canvas.create_text(current_x + scaled_width / 2, current_y + scaled_length + 5, text=f"Qty: {cut_quantity}", fill="black", anchor="n", tags="cut_sizes") current_y += scaled_length # Remove the gap between cut sizes # Adjust the canvas scroll region based on the actual drawing dimensions self.canvas.config(scrollregion=self.canvas.bbox("all")) def display_optimization_results(self, optimizer): # Display optimization results on the canvas result_text = f"Optimization Results:\nTotal sheets needed: {optimizer.sheets_needed}\nRemaining stock area: {optimizer.remaining_stock_area:.2f} mm²" self.canvas.create_text(400, 500, text=result_text, fill="black", anchor="center", tags="optimization_results") def export_to_pdf(self): try: pdf_filename = "cutting_plan.pdf" pdf = canvas.Canvas(pdf_filename, pagesize=(800, 600)) self.display_stock_size_to_pdf(pdf, float(self.stock_width_var.get()), float(self.stock_length_var.get()), int(self.stock_quantity_var.get())) self.display_cut_sizes_to_pdf(pdf, self.cut_sizes) self.display_optimization_results_to_pdf(pdf) # Pass optimizer object here pdf.save() messagebox.showinfo("PDF Export", f"The cutting plan has been exported to {pdf_filename}") except Exception as e: messagebox.showerror("Error", f"An error occurred while exporting to PDF: {str(e)}") def display_stock_size_to_pdf(self, pdf, stock_width, stock_length, stock_quantity): # Calculate total dimensions of stock sheet total_width = stock_width * stock_quantity total_length = stock_length # Draw the stock sheet rectangle on PDF pdf.rect(10, 10, total_width + 10, total_length + 10, fill=1) # Display stock size dimensions on PDF pdf.drawCentredString(total_width / 2 + 10, total_length / 2 + 10, f"Stock Size\n{stock_width} mm x {stock_length} mm x {stock_quantity}") def display_cut_sizes_to_pdf(self, pdf, cut_plan): current_x = 10 current_y = 10 for cut_width, cut_length, cut_quantity in cut_plan: # Scale dimensions for better visibility scale_factor = 10 scaled_width = cut_width * scale_factor scaled_length = cut_length * scale_factor # Draw the cut size rectangle on PDF for _ in range(cut_quantity): pdf.rect(current_x, current_y, scaled_width, scaled_length, fill=1) # Display cut size dimensions on PDF pdf.drawCentredString(current_x + scaled_width / 2, current_y - 5, f"{cut_width} mm") pdf.drawRightString(current_x - 5, current_y + scaled_length / 2, f"{cut_length} mm") # Display cut size quantity on PDF pdf.drawCentredString(current_x + scaled_width / 2, current_y + scaled_length + 5, f"Qty: {cut_quantity}") current_y += scaled_length + 10 def display_optimization_results_to_pdf(self, pdf): # Display optimization results on PDF result_text = f"Optimization Results:\nTotal sheets needed: {self.sheets_needed}\nRemaining stock area: {self.remaining_stock_area:.2f} mm²" pdf.drawCentredString(400, 500, result_text) if __name__ == "__main__": root = tk.Tk() app = GuillotineApp(root) root.mainloop()I need help to finding best 2d cutting optimization cutting plan on cutting layout.
It is not working to display well calculated and quality results for the same.