#include "agirlik_penceresi.hpp" #include #include #include #include #include "fiko/malzeme/malzeme.hpp" #include "fiko/sahne/sahne.hpp" #include "fiko/ui/pencere_cerceve.hpp" // ui::Pencere — merkezi pencere iskeleti #include "imgui.h" #include "ui_ortak.hpp" // agirlikOlcekle / agirlikBicim #include "uygulama_baglam.hpp" namespace fiko { namespace { // Malzeme atanmamış gövdeler için varsayılan yoğunluk (kg/m³) — MalzemeTanim'in // kendi varsayılanıyla aynı (çelik). Kullanıcı Ayarlar sekmesinden değiştirebilir. f64 s_varsayilanYogunluk = 2710.0; bool s_acik = false; bool s_ustte = false; int s_mod = 1; // 0=Tek Gövde, 1=Seçili Gövdeler, 2=Komple Sahne (varsayılan: hepsi) // Tek satırlık ağırlık sonucu (görüntüleme + toplam için). struct AgirlikSatir { std::string ad; f64 hacimMm3 = 0; f64 kutleKg = 0; std::string malzemeAd; // boş = varsayılan yoğunluk kullanıldı }; // Bir gövdenin kütlesini hesapla (malzeme atanmışsa onun yoğunluğu, yoksa varsayılan). AgirlikSatir govdeAgirligiHesapla(Dugum& d, const malzeme::MalzemeAtama& ata, const malzeme::MalzemeKutuphanesi& kut) { AgirlikSatir s; s.ad = d.ad.empty() ? "Gövde" : d.ad; s.hacimMm3 = d.hacim; const u32 mk = ata.govdeninMalzemesi(d.kimlik); const malzeme::MalzemeTanim* tanim = mk ? kut.bul(mk) : nullptr; if (tanim) { s.kutleKg = tanim->kutleKg(d.hacim); s.malzemeAd = tanim->ad; } else { s.kutleKg = d.hacim * s_varsayilanYogunluk * 1e-9; // kütle[kg] = hacim[mm³]·ρ[kg/m³]·1e-9 } return s; } // Aktif moda göre hesaplanacak gövde listesini çıkar (hacimsiz düğümler — sketch/ // datum/grup — hariç: hacim>0 filtresi tip enum'una bağımlı olmadan doğru sonucu verir). std::vector satirlariCikar(UygulamaBaglam& b, bool& tekFazla) { std::vector satirlar; tekFazla = false; if (s_mod == 2) { // Komple Sahne for (Dugum& d : b.sahne.dugumler()) if (d.hacim > 1e-6) satirlar.push_back(govdeAgirligiHesapla(d, b.malzemeAta, b.malzemeKut)); } else { // Tek Gövde / Seçili Gövdeler — ikisi de seçimden gelir const std::vector sec = b.sahne.seciliGovdeler(); if (s_mod == 0) { // Tek Gövde: yalnız ilk seçili if (sec.size() > 1) tekFazla = true; if (!sec.empty()) if (Dugum* d = b.sahne.bul(sec.front()); d && d->hacim > 1e-6) satirlar.push_back(govdeAgirligiHesapla(*d, b.malzemeAta, b.malzemeKut)); } else { // Seçili Gövdeler (grup) for (u32 g : sec) if (Dugum* d = b.sahne.bul(g); d && d->hacim > 1e-6) satirlar.push_back(govdeAgirligiHesapla(*d, b.malzemeAta, b.malzemeKut)); } } return satirlar; } } // namespace void agirlikPencereAc() { s_acik = !s_acik; } bool agirlikPencereAcikMi() { return s_acik; } void agirlikPenceresiCiz(UygulamaBaglam& b) { if (!s_acik) return; const f32 ekranG = ImGui::GetIO().DisplaySize.x; ImGui::SetNextWindowPos({ekranG - 340, 92}, ImGuiCond_FirstUseEver); ui::Pencere pen{"⚖ Ağırlık Hesaplama", &s_acik, {.boyut = {320, 0}, .pinDurum = &s_ustte}}; if (!pen) return; // Mod sekmeleri const auto sekme = [&](const char* et, int m, const char* ipucu) { const bool aktif = s_mod == m; if (aktif) ImGui::PushStyleColor(ImGuiCol_Button, {0.13f, 0.50f, 0.85f, 1.0f}); if (ImGui::Button(et, {0, 0})) s_mod = m; if (aktif) ImGui::PopStyleColor(); if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", ipucu); }; sekme("◼ Tek Gövde", 0, "Sahnede seçili TEK gövdenin ağırlığı"); ImGui::SameLine(); sekme("▦ Seçili Gövdeler", 1, "Sahnede seçili TÜM gövdelerin toplam ağırlığı"); ImGui::SameLine(); sekme("⬛ Komple Sahne", 2, "Sahnedeki TÜM gövdelerin toplam ağırlığı"); ImGui::Separator(); // ImGui::SetNextItemWidth(-1); float yog = (float)s_varsayilanYogunluk; if (ImGui::DragFloat("Varsayılan Yoğunluk (kg/m³)", &yog, 5.0f, 1.0f, 25000.0f, "%.0f")) s_varsayilanYogunluk = yog; ImGui::TextDisabled("Malzeme atanmamış gövdeler için kullanılır (Malzeme penceresinden atayın)."); ImGui::Separator(); bool tekFazla = false; std::vector satirlar = satirlariCikar(b, tekFazla); if (s_mod == 0 && tekFazla) ImGui::TextColored({1.0f, 0.7f, 0.35f, 1.0f}, "Birden çok gövde seçili — yalnız ilki gösteriliyor."); if (satirlar.empty()) { ImGui::TextDisabled(s_mod == 2 ? "Sahnede hacimli (katı) gövde yok." : "3D'de bir/birkaç gövde seçin."); } else { if (ImGui::BeginTable("##agirlikTablo", 4, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_SizingStretchProp)) { ImGui::TableSetupColumn("Gövde"); ImGui::TableSetupColumn("Malzeme"); ImGui::TableSetupColumn("Hacim (cm³)"); ImGui::TableSetupColumn("Kütle"); ImGui::TableHeadersRow(); f64 toplamKg = 0, toplamHacim = 0; for (const AgirlikSatir& s : satirlar) { toplamKg += s.kutleKg; toplamHacim += s.hacimMm3; ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(s.ad.c_str()); ImGui::TableSetColumnIndex(1); if (s.malzemeAd.empty()) ImGui::TextDisabled("Varsayılan"); else ImGui::TextUnformatted(s.malzemeAd.c_str()); ImGui::TableSetColumnIndex(2); ImGui::Text("%.2f", s.hacimMm3 * 1e-3); // mm³ → cm³ ImGui::TableSetColumnIndex(3); ImGui::TextColored({1.0f, 0.82f, 0.35f, 1.0f}, "%s", agirlikBicim(s.kutleKg).c_str()); } ImGui::EndTable(); ImGui::Separator(); ImGui::TextColored({0.35f, 0.85f, 0.9f, 1.0f}, "Toplam (%zu gövde):", satirlar.size()); ImGui::SameLine(); const std::string toplamMetin = agirlikBicim(toplamKg); ImGui::TextColored({1.0f, 0.82f, 0.35f, 1.0f}, "%s", toplamMetin.c_str()); ImGui::TextDisabled("Toplam hacim: %.2f cm³", toplamHacim * 1e-3); char kopyala[96]; std::snprintf(kopyala, sizeof(kopyala), "%s", toplamMetin.c_str()); if (ImGui::SmallButton("Kopyala")) ImGui::SetClipboardText(kopyala); } } } } // namespace fiko