import gradio as gr import pandas as pd from rectpack import newPacker import matplotlib.pyplot as plt import matplotlib.patches as patches import random # --- Hesaplama Fonksiyonları --- def calculate_single_cabinet_parts(dolap_no, h, w, d, kalinlik, raf_sayisi, kapak_var, kapak_sayisi, arkalik_var): """Tek bir dolabın parçalarını hesaplar.""" parts = [] # Ana Gövde Parçaları ic_genislik = w - (2 * kalinlik) parts.append({'dolap_no': dolap_no, 'parca_adi': 'Yan Tabla', 'adet': 2, 'uzunluk': h, 'genislik': d, 'malzeme': 'Sunta'}) parts.append({'dolap_no': dolap_no, 'parca_adi': 'Alt/Üst Tabla', 'adet': 2, 'uzunluk': ic_genislik, 'genislik': d, 'malzeme': 'Sunta'}) # Raflar if raf_sayisi > 0: raf_derinlik = d - 1 parts.append({'dolap_no': dolap_no, 'parca_adi': 'Raf', 'adet': raf_sayisi, 'uzunluk': ic_genislik, 'genislik': raf_derinlik, 'malzeme': 'Sunta'}) # Kapaklar (Revize Edilmiş Hesaplama) if kapak_var and kapak_sayisi > 0: calisma_boslugu = 3 bant_payi = 1 kapak_yukseklik = h - calisma_boslugu toplam_kullanilabilir_genislik = w - calisma_boslugu bitmis_kapak_genisligi = toplam_kullanilabilir_genislik / kapak_sayisi net_kesim_genisligi = bitmis_kapak_genisligi - (2 * bant_payi) parts.append({'dolap_no': dolap_no, 'parca_adi': 'Kapak', 'adet': kapak_sayisi, 'uzunluk': kapak_yukseklik, 'genislik': round(net_kesim_genisligi, 2), 'malzeme': 'Sunta'}) # Arkalık if arkalik_var: parts.append({'dolap_no': dolap_no, 'parca_adi': 'Arkalık', 'adet': 1, 'uzunluk': h, 'genislik': w, 'malzeme': 'HDF/Duralit'}) return parts def add_cabinet_to_list(all_parts_state, cabinet_number_state, h, w, d, kalinlik, raf_sayisi, kapak_var, kapak_sayisi, arkalik_var): """Hesaplanan dolap parçalarını ana listeye ekler.""" if not all([h, w, d, kalinlik]): raise gr.Error("Lütfen temel dolap ölçülerini ve malzeme kalınlığını girin!") new_parts = calculate_single_cabinet_parts(cabinet_number_state, h, w, d, kalinlik, raf_sayisi, kapak_var, kapak_sayisi, arkalik_var) updated_parts = all_parts_state + new_parts df = pd.DataFrame(updated_parts) return updated_parts, cabinet_number_state + 1, df, f"Başarılı! {cabinet_number_state}. Dolap listeye eklendi." def clear_list(): """Tüm listeyi temizler.""" return [], 1, pd.DataFrame(), "Liste temizlendi. Yeni dolap ekleyebilirsiniz." def create_layout_plot(packer, plaka_uzunluk, plaka_genislik): """Matplotlib kullanarak plaka yerleşimini çizer.""" images = [] plaka_alani = plaka_uzunluk * plaka_genislik for i, b in enumerate(packer): fig, ax = plt.subplots(1, figsize=(10, 7)) ax.set_xlim(0, plaka_uzunluk) ax.set_ylim(0, plaka_genislik) # Plaka sınırını çiz ax.add_patch(patches.Rectangle((0, 0), plaka_uzunluk, plaka_genislik, fill=False, edgecolor='black', lw=2)) toplam_kullanilan_alan = 0 for r in b: # Rastgele bir renk oluştur color = "#{:06x}".format(random.randint(0, 0xFFFFFF)) ax.add_patch(patches.Rectangle((r.x, r.y), r.width, r.height, facecolor=color, edgecolor='black', lw=1, alpha=0.7)) # Parça ölçülerini yaz ax.text(r.x + r.width/2, r.y + r.height/2, f"{int(r.width)}x{int(r.height)}", ha='center', va='center', fontsize=8) toplam_kullanilan_alan += r.width * r.height kullanim_orani = (toplam_kullanilan_alan / plaka_alani) * 100 ax.set_title(f"Plaka {i+1} - Kullanım: {kullanim_orani:.2f}%") plt.gca().set_aspect('equal', adjustable='box') filepath = f"/tmp/plaka_{i+1}.png" plt.savefig(filepath) plt.close(fig) images.append(filepath) return images def run_optimization_and_visualize(all_parts, plaka_uzunluk, plaka_genislik): """Parçaları plakalara yerleştirir ve görselleştirir.""" if not all_parts: raise gr.Error("Liste boş! Lütfen önce dolap ekleyin.") if not all([plaka_uzunluk, plaka_genislik]): raise gr.Error("Lütfen sunta plakası ölçülerini girin!") sunta_parcalari = [] for part in all_parts: if part['malzeme'] == 'Sunta': for _ in range(part['adet']): sunta_parcalari.append((part['uzunluk'], part['genislik'])) if not sunta_parcalari: return "Optimize edilecek 'Sunta' malzemesi bulunamadı.", None packer = newPacker(rotation=True) for r in sunta_parcalari: packer.add_rect(r[0], r[1]) packer.add_bin(plaka_uzunluk, plaka_genislik, count=100) packer.pack() plaka_sayisi = len(packer) optimization_result = f"**Optimizasyon Sonucu:**\nToplam **{plaka_sayisi}** adet {plaka_uzunluk}x{plaka_genislik}mm sunta plakasına ihtiyaç var." # Görselleştirmeyi oluştur image_paths = create_layout_plot(packer, plaka_uzunluk, plaka_genislik) return optimization_result, image_paths # --- Gradio Arayüzü --- with gr.Blocks(theme=gr.themes.Soft(), title="Dolap Kesim Hesaplayıcı") as demo: all_parts_state = gr.State([]) cabinet_number_state = gr.State(1) gr.Markdown("# Akıllı Dolap Kesim Hesaplayıcı ve Görselleştirici") gr.Markdown("Bu uygulama, dolap ölçülerinize göre kesim listesi oluşturur ve parçaların plaka üzerindeki yerleşimini görselleştirir.") with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 1. Dolap Bilgilerini Girin") with gr.Accordion(f"Yeni Dolap Ekle (No: 1)", open=True) as accordion: with gr.Row(): h_input = gr.Number(label="Yükseklik (mm)", value=1800) w_input = gr.Number(label="Genişlik (mm)", value=800) d_input = gr.Number(label="Derinlik (mm)", value=500) kalinlik_input = gr.Number(label="Malzeme Kalınlığı (mm)", value=18) raf_input = gr.Slider(minimum=0, maximum=10, step=1, label="Raf Sayısı", value=3) with gr.Row(): kapak_var_input = gr.Checkbox(label="Kapak Olsun mu?", value=True) kapak_sayisi_input = gr.Radio([1, 2, 3, 4], label="Kapak Sayısı", value=2, interactive=True) arkalik_var_input = gr.Checkbox(label="Arkalık Olsun mu?", value=True) add_button = gr.Button("Hesapla ve Listeye Ekle", variant="primary") clear_button = gr.Button("Tüm Listeyi Temizle", variant="stop") status_text = gr.Textbox(label="Durum", interactive=False) with gr.Column(scale=2): gr.Markdown("### 2. Toplam Parça Kesim Listesi") parts_df_output = gr.DataFrame( headers=["dolap_no", "parca_adi", "adet", "uzunluk", "genislik", "malzeme"], interactive=False ) gr.Markdown("---") gr.Markdown("### 3. Optimizasyon ve Görselleştirme") with gr.Row(): plaka_uzunluk_input = gr.Number(label="Plaka Uzunluğu (mm)", value=2800) plaka_genislik_input = gr.Number(label="Plaka Genişliği (mm)", value=2100) visualize_button = gr.Button("Optimizasyonu Çalıştır ve Görselleştir", variant="primary") optimization_output = gr.Markdown() layout_gallery = gr.Gallery(label="Plaka Yerleşim Planları", elem_id="gallery", columns=[2], object_fit="contain", height="auto") # Fonksiyon Bağlantıları kapak_var_input.change(lambda x: gr.update(interactive=x), kapak_var_input, kapak_sayisi_input) add_button.click( fn=add_cabinet_to_list, inputs=[all_parts_state, cabinet_number_state, h_input, w_input, d_input, kalinlik_input, raf_input, kapak_var_input, kapak_sayisi_input, arkalik_var_input], outputs=[all_parts_state, cabinet_number_state, parts_df_output, status_text] ).then(lambda cabinet_no: gr.update(label=f"Yeni Dolap Ekle (No: {cabinet_no})"), cabinet_number_state, accordion) clear_button.click(fn=clear_list, outputs=[all_parts_state, cabinet_number_state, parts_df_output, status_text]).then(lambda cabinet_no: gr.update(label=f"Yeni Dolap Ekle (No: {cabinet_no})"), cabinet_number_state, accordion) visualize_button.click( fn=run_optimization_and_visualize, inputs=[all_parts_state, plaka_uzunluk_input, plaka_genislik_input], outputs=[optimization_output, layout_gallery] ) demo.launch()