Dolap1 / app.py
Zatimm's picture
Update app.py
c1f2907 verified
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()