#include "cam_parca_op_penceresi.hpp" #include #include #include #include "fiko/cam/cam_secim.hpp" #include "fiko/cam/cam_sistemi.hpp" #include "fiko/cam/part_operasyon.hpp" #include "fiko/cekirdek/cekirdek.hpp" #include "fiko/sahne/sahne.hpp" #include "fiko/ui/bilesen.hpp" #include "fiko/ui/form.hpp" #include "fiko/ui/pencere_cerceve.hpp" #include "fiko/ui/tema.hpp" #include "imgui.h" #include "pencere_util.hpp" namespace fiko { namespace { using cam::CamSecimKip; using cam::CamSistemi; using cam::Kontrolcu; using cam::MakineKinematik; using cam::PartOperasyon; using cam::Stok; using cam::StokTip; using cam::WorkOffset; // Op-basina pencere pin ("ustte tut") durumu — UI-only, kalici degil. std::unordered_map g_parcaOpPin; // Op-basina acik-durum — cam_paneli.cpp g_pinDurum/acikPencereler kalibi. std::unordered_map g_parcaOpAcik; // f64 icin DragScalar sarimi (cam_paneli.cpp surukleF64 kopyasi). bool surukleF64(const char* etiket, f64& deger, f32 hiz = 0.1f, const char* fmt = "%.3f") { return ImGui::DragScalar(etiket, ImGuiDataType_Double, °er, hiz, nullptr, nullptr, fmt); } // Vec3d (bellek: x,y,z ardisik f64) icin 3'lu DragScalarN. bool surukleVec3(const char* etiket, Vec3d& v, f32 hiz = 0.1f, const char* fmt = "%.2f") { return ImGui::DragScalarN(etiket, ImGuiDataType_Double, &v.x, 3, hiz, nullptr, nullptr, fmt); } // "🎯 Yüzeyden Seç" gerçek düğme: part-op modu başlat (aktifse cyan). ayarlaVec // ile seçilen yüzün (nokta, normal)'i callback'e gider. Toggle: tekrar tık=bitir. void yuzeydenSecDugmesi(CamSistemi& cam, u32 popKimlik, const char* id, const char* ipucu, std::function ayarlaVec) { ImGui::SameLine(); ImGui::PushID(id); const bool aktif = cam.secim().partOpAktifMi(popKimlik, CamSecimKip::DuzlemUst); if (aktif) ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{0.08f, 0.42f, 0.55f, 1.0f}); if (ImGui::SmallButton("🎯")) cam.secim().partOpBaslat(popKimlik, CamSecimKip::DuzlemUst, {}, std::move(ayarlaVec), [] {}); if (aktif) ImGui::PopStyleColor(); ImGui::PopID(); ImGui::SetItemTooltip("%s", ipucu); } void eksenBolumu(CamSistemi& cam, PartOperasyon& op) { if (!fiko::ui::bolum("📐", "İşleme Ekseni (Machining Axis System)")) return; const ImVec4 SOLUK = ui::tema().metinSoluk; ImGui::TextColored(SOLUK, "G-kod bu eksen sistemine göre üretilir"); ImGui::Spacing(); surukleVec3("Origin", op.eksenOrigin, 0.1f, "%.2f"); yuzeydenSecDugmesi(cam, op.kimlik, "axO", "Sahnede yüze tıkla → origin yüz merkezine oturur", [&op](Vec3d nokta, Vec3d) { op.eksenOrigin = nokta; }); surukleVec3("Z Ekseni", op.eksenZ, 0.01f, "%.3f"); yuzeydenSecDugmesi(cam, op.kimlik, "axZ", "Sahnede yüze tıkla → Z ekseni yüz normaline hizalanır", [&op](Vec3d nokta, Vec3d normal) { op.eksenZ = normal; op.eksenOrigin = nokta; }); ui::alan("X Ekseni"); surukleVec3("##X Ekseni", op.eksenX, 0.01f, "%.3f"); ui::alan("Y Ekseni"); surukleVec3("##Y Ekseni", op.eksenY, 0.01f, "%.3f"); } void makineBolumu(PartOperasyon& op) { if (!fiko::ui::bolum("🖥", "Makine")) return; { char buf[96]; std::snprintf(buf, sizeof(buf), "%s", op.makineAdi.c_str()); ui::alan("Makine Adı"); if (ImGui::InputText("##Makine Adı", buf, sizeof(buf))) op.makineAdi = buf; } ui::alan("Kinematik"); if (ImGui::BeginCombo("##Kinematik", cam::makineKinematikAdi(op.kinematik))) { for (int i = 0; i <= (int)MakineKinematik::BesEksen; ++i) { const auto k = (MakineKinematik)i; if (ImGui::Selectable(cam::makineKinematikAdi(k), k == op.kinematik)) op.kinematik = k; } ImGui::EndCombo(); } ui::alan("Kontrolcü (Post)"); if (ImGui::BeginCombo("##Kontrolcü", cam::kontrolcuAdi(op.kontrolcu))) { for (int i = 0; i <= (int)Kontrolcu::Generic; ++i) { const auto k = (Kontrolcu)i; if (ImGui::Selectable(cam::kontrolcuAdi(k), k == op.kontrolcu)) op.kontrolcu = k; } ImGui::EndCombo(); } } void workOffsetBolumu(PartOperasyon& op) { if (!fiko::ui::bolum("📍", "Work Offset")) return; ui::alan("Çalışma Sıfırı"); if (ImGui::BeginCombo("##Çalışma Sıfırı", cam::workOffsetAdi(op.workOffset))) { for (int i = 0; i <= (int)WorkOffset::G59; ++i) { const auto w = (WorkOffset)i; if (ImGui::Selectable(cam::workOffsetAdi(w), w == op.workOffset)) op.workOffset = w; } ImGui::EndCombo(); } } void hareketBolumu(PartOperasyon& op) { if (!fiko::ui::bolum("🛡", "Hareket / Güvenlik")) return; ui::alan("Hızlı Hareket (mm/dk)"); surukleF64("##Hızlı Hareket", op.hizliHareketOrani, 100.0f, "%.0f"); ImGui::SetItemTooltip("Rapid rate — takımın işlemesiz hareket hızı"); ui::alan("Takım Değişim Poz."); surukleVec3("##Takım Değişim Poz.", op.takimDegisimPoz, 0.5f, "%.1f"); ui::alan("Spindle Min (rpm)"); surukleF64("##Spindle Min", op.spindleMin, 10.0f, "%.0f"); ui::alan("Spindle Maks (rpm)"); surukleF64("##Spindle Maks", op.spindleMaks, 100.0f, "%.0f"); ui::anahtarSatiri("Soğutma (flood) varsayılan açık", &op.sogutmaVarsayilan); ui::alan("Güvenlik Düzlemi (Z)"); surukleF64("##Güvenlik Düzlemi", op.guvenlikDuzlemi, 0.5f, "%.2f"); ImGui::SetItemTooltip("Clearance Z — güvenli hızlı hareket düzlemi"); } // Stok/fikstür kaynak gövde seçim düğmesi (gerçek): part-op Stok modu başlat. void govdeSecDugmesi(CamSistemi& cam, u32 popKimlik, const char* id, const char* ipucu, std::function ayarla) { ImGui::SameLine(); ImGui::PushID(id); const bool aktif = cam.secim().partOpAktifMi(popKimlik, CamSecimKip::Stok); if (aktif) ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{0.08f, 0.42f, 0.55f, 1.0f}); if (ImGui::SmallButton("🎯")) cam.secim().partOpBaslat(popKimlik, CamSecimKip::Stok, std::move(ayarla), {}, [] {}); if (aktif) ImGui::PopStyleColor(); ImGui::PopID(); ImGui::SetItemTooltip("%s", ipucu); } void stokBolumu(CamSistemi& cam, PartOperasyon& op) { if (!fiko::ui::bolum("🧱", "Stok (Kütük)")) return; const ImVec4 SOLUK = ui::tema().metinSoluk; const ImVec4 YESIL = ui::tema().basari; const ImVec4 KIRMIZI = ui::tema().hata; Stok& s = op.stok; ui::alan("Tip"); if (ImGui::BeginCombo("##Tip", cam::stokTipAdi(s.tip))) { for (int i = 0; i <= (int)StokTip::GovdeOffset; ++i) { const auto t = (StokTip)i; if (ImGui::Selectable(cam::stokTipAdi(t), t == s.tip)) s.tip = t; } ImGui::EndCombo(); } switch (s.tip) { case StokTip::Kutu: ui::alan("Boyut (X/Y/Z)"); surukleVec3("##Boyut", s.boyut, 0.5f, "%.2f"); break; case StokTip::Silindir: ui::alan("Çap (mm)"); surukleF64("##Çap", s.boyut.x, 0.5f, "%.2f"); ui::alan("Boy (mm)"); surukleF64("##Boy", s.boyut.z, 0.5f, "%.2f"); break; case StokTip::GovdeOffset: { ui::alan("Pay (mm)"); surukleF64("##Pay", s.pay, 0.1f, "%.2f"); ImGui::SetItemTooltip("Kaynak gövde etrafına eklenecek malzeme payı"); const bool bagli = s.kaynakGovde != 0; if (bagli) ImGui::TextColored(YESIL, "● Kaynak Gövde: #%u", s.kaynakGovde); else ImGui::TextColored(KIRMIZI, "● Kaynak Gövde: seçilmedi"); govdeSecDugmesi(cam, op.kimlik, "stokGovde", "Sahnede kaynak gövdeye tıkla", [&s](u32 g) { s.kaynakGovde = g; }); break; } } ui::alan("Origin"); surukleVec3("##Origin", s.origin, 0.5f, "%.2f"); ImGui::SeparatorText("Fikstür"); const bool fVar = op.fiksturRef != 0; if (fVar) ImGui::TextColored(YESIL, "● Fikstür: ref #%u", op.fiksturRef); else ImGui::TextColored(SOLUK, "○ Fikstür: yok (opsiyonel)"); govdeSecDugmesi(cam, op.kimlik, "fikstur", "Sahnede fikstür gövdesine tıkla", [&op](u32 g) { op.fiksturRef = g; }); if (fVar) { ImGui::SameLine(); if (ImGui::SmallButton("✕##fikstur")) op.fiksturRef = 0; } } // Tek parca operasyonunun yuzen/pinlenebilir penceresi. Ayni anda birden fazla // acik olabilir (###camparcaop_ benzersiz). Kapaninca g_parcaOpAcik'tan // cikar. Web fiko-cam-part-op-dialog.ts eslenigi. void parcaOpPenceresiCiz(CamSistemi& cam, PartOperasyon& op) { using namespace fiko::ui; using u32 = fiko::u32; // ui::u32(ImVec4) ile tip cakismasini onler const ImVec4 CYAN = ui::tema().vurgu; const ImVec4 SOLUK = ui::tema().metinSoluk; bool& ustte = g_parcaOpPin[op.kimlik]; char baslik[176]; std::snprintf(baslik, sizeof(baslik), "⚙ %s###camparcaop_%u", op.ad.c_str(), op.kimlik); bool acik = true; { Pencere p{baslik, &acik, {.boyut = {320, 0}, .pinDurum = &ustte}}; if (p) { // ---- Ad (inline duzenlenebilir) ---- { char buf[96]; std::snprintf(buf, sizeof(buf), "%s", op.ad.c_str()); ImGui::SetNextItemWidth(-1); if (ImGui::InputText("##ad", buf, sizeof(buf))) op.ad = buf; } const bool aktif = cam.aktifParcaOp == (int)op.kimlik; ImGui::TextColored(aktif ? CYAN : SOLUK, aktif ? "● Aktif parça operasyonu" : "○ Pasif"); ImGui::TextColored(SOLUK, "%d operasyon bağlı", (int)op.operasyonlar.size()); // Uzun form 3 ikon sekmeye bölündü → pencere yüksekliği oturur, scroll gerekmez. if (sekmeBaslat("parcaOpSekmeler")) { if (sekme("Eksen", "📐")) { eksenBolumu(cam, op); sekmeBitir(); } if (sekme("Makine", "🖥")) { makineBolumu(op); workOffsetBolumu(op); hareketBolumu(op); sekmeBitir(); } if (sekme("Stok", "🧱")) { stokBolumu(cam, op); sekmeBitir(); } sekmeKapat(); } // ---- Alt eylem cubugu: Aktif Yap / Sil ---- ImGui::Separator(); if (!aktif && ImGui::Button("◉ Aktif Yap", {-48, 0})) cam.aktifParcaOp = (int)op.kimlik; if (!aktif) ImGui::SameLine(); if (ikonButon("🗑", "Parça operasyonunu sil")) { if (cam.secim().partOpKimlik() == op.kimlik) cam.secim().bitir(); cam.parcaOpSil(op.kimlik); g_parcaOpAcik[op.kimlik] = false; } } } if (!acik) g_parcaOpAcik[op.kimlik] = false; } } // namespace void camParcaOpPencereAc(u32 kimlik) { g_parcaOpAcik[kimlik] = true; } void camParcaOpPencereleriCiz(Cekirdek& cekirdek, Sahne& sahne, cam::CamSistemi& cam) { (void)cekirdek; (void)sahne; for (auto& [kimlik, acik] : g_parcaOpAcik) { if (!acik) continue; PartOperasyon* op = cam.parcaOpBul(kimlik); if (!op) { acik = false; // silinmis/gecersiz kimlik → ayikla continue; } parcaOpPenceresiCiz(cam, *op); } } } // namespace fiko