File size: 8,564 Bytes
bc6da79
3b04ccf
 
c1f2907
 
 
3b04ccf
 
 
 
 
 
 
c1f2907
3b04ccf
c1f2907
3b04ccf
 
c1f2907
3b04ccf
 
 
 
c1f2907
3b04ccf
 
c1f2907
3b04ccf
0496fb1
 
 
c1f2907
0496fb1
c1f2907
3b04ccf
 
0eafb4f
3b04ccf
 
c1f2907
3b04ccf
 
 
c1f2907
3b04ccf
c1f2907
3b04ccf
 
 
 
 
 
c1f2907
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3b04ccf
 
 
 
 
 
 
 
 
 
 
c1f2907
 
3b04ccf
c1f2907
3b04ccf
 
 
c1f2907
3b04ccf
 
 
 
 
c1f2907
 
3b04ccf
c1f2907
3b04ccf
 
 
 
 
 
 
c1f2907
 
9b4608f
de1e9e4
3b04ccf
 
c1f2907
3b04ccf
 
 
 
 
 
 
 
 
 
 
 
 
 
0eafb4f
3b04ccf
 
c1f2907
3b04ccf
 
de1e9e4
c1f2907
 
 
 
 
3b04ccf
c1f2907
 
 
3b04ccf
c1f2907
 
3b04ccf
 
c1f2907
3b04ccf
c1f2907
 
 
 
3b04ccf
c1f2907
9e01a05
bc6da79
3b04ccf
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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()