#pragma once #include #include #include #include #include "belge.hpp" #include "belge_ciz.hpp" #include "isik_durum.hpp" namespace fiko { class ImGuiKatman; struct UygulamaBaglam; // bekleyenIjkHedef tüketimi için (kafa_penceresi.cpp'de tanımlı) // ============================================================================ // KafaPanel — açılı kafa mini-viewport paneli (web fiko-mini-3d / ozmo dialog eşi). // İKİ kafayı da sürer (tanım-güdümlü, kod kopyası YOK): // • FikoYT Diagonal Kafa (web SahneWtecKafa + bAcisiUst/cAcisiAlt) // • FikoYT Ozmo Kafa (web SahneOzmoKafa + UstAciOzmo/AltAciOzmo) // Kendi kendine yeten tek-kayıtlık belge penceresi: // ÜST : kafa 3D'si (render-to-texture ImGui::Image, kendi ViewportHedef'i) // ALT : Açı→IJK / IJK→Açı / Ayarlar sekmeleri // BelgeYonetici 3-fazlı akışının TEK-KAYIT eşi (her iki kafa için de koşar): // 1) kafaGuncelle → belgeHedefleriniGuncelle (lazy kur + hedef/doku + anim + kayıt) // 2) kafaPencereCiz → belgePencereleriCiz (ImGui::Image + kamera jesti + kontroller) // 3) kafaKaydet → belgeleriKaydet (belgeCiz ile GPU record) // ============================================================================ enum class KafaTip : u8 { Diagonal = 0, Ozmo = 1 }; constexpr int kKafaSayi = 2; // Bir kafanın DEĞİŞMEZ tanımı (kinematik + varlık + kimlik). İki makine yapısal olarak // FARKLI — parametre değil, formül farkı da var (bkz. bAciDeg/cAciDeg, KafaTip anahtarı): // Diagonal: C EĞİK eksende (0.00617,0.70708,-0.707107), pivot uzakta, C 0..360. // Ozmo: C dünya -X ekseninde, pivot (0,0,-83.8), C -94..94, B formülü 180−(...). struct KafaTanim { KafaTip tip = KafaTip::Diagonal; const char* ad = ""; // "FikoYT Diagonal Kafa" const char* pencereKimlik = ""; // ImGui "###" kalıcı kimliği const char* ustYol = ""; // B (üst) parça VRML const char* altYol = ""; // C (alt) parça VRML Vec3d cEksen{0, 0, 1}; // C dönüş ekseni (birim) Vec3d cPivotMm{}; // C pivot noktası (mm — importer ölçeği uygulanır) // Pens/mil burnu referans noktası (mm, C'nin YEREL çerçevesinde) — web'deki // CAcisiAlt/AltAciOzmo'daki takim.position.set(...) sabitiyle BİREBİR aynı. Takımın // kendi yerel orijini KESME UCU'dur (FikoTakimFrezeleme: uç z=0, gövde +Z'ye uzar); // dünyada takım ucu = takimReferansMm − (0,0,boy) − (0,0,kaçma) (kafaAciUygula uygular). Vec3d takimReferansMm{}; f32 takimCapVars = 10.0f, takimBoyVars = 60.0f; // takım göstergesi varsayılan çap/boy (mm) f32 bKalibVars = 0.0f; // B kalibrasyon varsayılanı f32 cKalibVars = 0.0f; // C kalibrasyon varsayılanı f32 cMin = 0.0f, cMax = 360.0f; // C açı aralığı (Ozmo: -94..94) const char* kameraAnahtar = ""; // kamera duruşu kalıcılık anahtarı const char* yardimDosya = ""; // assets/yardim/ const char* aracKimlik = ""; // araç kipi/lisans kimliği ("arac.diagonal_kafa") }; const KafaTanim& kafaTanim(KafaTip t); // Aynı takım yönü (I/J/K) için geçerli bir B/C duruşu. B ekseni dünya-Z olduğundan // Z-dönüşü v(c)=qC·baz'ın z bileşenini değiştirmez → çözüm koşulu YALNIZ C'ye bağlıdır // (v(c).z == hedef.z) ve tipik olarak 2 kök verir; her C için B analitik olarak tektir. // Bu yüzden aynı yön birden fazla duruşla elde edilir (çarpışma/limit seçimi kullanıcıya). struct KafaCozum { f32 b = 0, c = 0, sapma = 0; }; struct KafaDurum { const KafaTanim* tanim = nullptr; // hangi kafa (kafaDurum kurar) std::unique_ptr belge; std::unique_ptr hedef; CizimOnbellek cizim; u64 doku = 0; // ImGui doku kaydı (ImTextureID) VkImageView kayitliGorunum = VK_NULL_HANDLE; bool acik = false; // pencere görünür mü bool yuklendi = false; // kafa parçaları içe aktarıldı mı u32 bNode = 0, cNode = 0; // B (üst) / C (alt) düğüm kimlikleri u32 takimNode = 0; // uca takılı takım göstergesi (C'nin "çocuğu") // ---- Kinematik çalışma değerleri (varsayılanlar tanımdan gelir) ---- f32 bAci = 0.0f, cAci = 0.0f; // kullanıcı B/C açısı (derece) f32 bKalib = 0.0f, cKalib = 0.0f; // kalibrasyon ofseti int bYon = 1, cYon = 1; // 1 = saat tersi, 2 = saat yönü bool isikAcik = true; bool ustte = false; // pencere "üstte tut" (pin) durumu // ---- Uca takılı takım göstergesi (gerçek profil mesh'i — takimGostergeMeshKur; // web'deki yarım FikoTakimFrezeleme örneğinin yerini tutar) — kinematik zincire // (kafaAciUygula) doğrudan bağlı; C'nin ucundan "kaçma" kadar kaydırılır. Tüm ölçüler mm. bool takimGoster = true; // gösterge çizimi açık mı f32 takimCap = 10.0f; // mm, gösterge çapı f32 takimBoy = 60.0f; // mm, gösterge boyu (tabandan uca) f32 takimKacma = 0.0f; // mm, taban ofseti — C ucu boyunca (+ dışarı, − içeri) f32 takimBoncukRadius = 0.0f; // mm, uç köşe/boncuk radüsü — 0=düz takım (flat end mill), // 00 iken anlamlı); // false (varsayılan): kesme ucuna göre (eski davranış). // ---- Kaçma değerleri önbelleği — yalnız girdi (açı/takım) değişince yeniden // hesapla (bkz. kacmaDegerleriOnbellekli); ImGui her kare çizse de ağır analitik // hesap kare-başı TEKRARLANMAZ. "Açı → IJK" ve "IJK → Açı" sekmeleri ORTAK kullanır. Vec3d kacmaOnbellek{}; // Ham ekstremler (X+/X−/Y+/Y−/Z+/Z− ayrı ayrı) — tezgahçı takımı hangi taraftan // (X+/X−/Y+/Y−/Z+/Z−) parçaya değdirdiyse, o yönün DOĞRU işaretli kaçma değerini // (temas noktası → takım ucu/küre merkezi ofseti) buradan okur. kacmaOnbellek tek // otomatik-seçilmiş (web ile birebir) değerdir; ters taraftan dokunulduysa işareti // yanlış yorumlanabilir. Vec3d kacmaOnbellekMin{}, kacmaOnbellekMax{}; bool kacmaOnbellekGecerli = false; f32 kacmaSonBAci = 0.0f, kacmaSonCAci = 0.0f; f32 kacmaSonCap = 0.0f, kacmaSonBoy = 0.0f, kacmaSonKacmaOfset = 0.0f, kacmaSonBoncukRadius = 0.0f; bool kacmaSonBoncukMerkez = false; // ---- Doğrusal nokta ofseti — kullanıcı bir mesafe (mm) girer, o anki takım // ekseni (I/J/K) boyunca o mesafedeki NOKTANIN X/Y/Z koordinatlarını okur (basit // vektör ölçekleme: nokta = mesafe × birim(I,J,K)). kacmaDegerleriHesapla'dan // (takım PROFİLİ/gövde ekstremleri) FARKLI — burada takım nokta kabul edilir, // önbellek gerekmez (O(1)). Hem "Açı → IJK" hem "IJK → Açı" sekmesi kullanır. f32 noktaMesafe = 1.0f; // mm, kullanıcı girdisi bool noktaOfsetiAcik = false; // "Doğrusal Nokta Ofseti" ayrı penceresi görünür mü bool kacmaAcik = false; // "Kaçma Değerleri" ayrı penceresi görünür mü bool takimGostergeAcik = false; // "Takım Göstergesi" ayrı penceresi görünür mü // ---- Takım ekseni (I/J/K) hedefi + sapma ---- f32 iDeger = 0.0f, jDeger = 0.0f, kDeger = 1.0f; // hedef takım yönü (dünya) f32 sapma = 0.0f; // mevcut B/C ile hedef I/J/K arasındaki açı farkı (derece) bool araniyor = false; // "Açıyı Bul" çalışıyor mu (senkron → anlık) // ---- Hedef I/J/K'yı sağlayan TÜM B/C duruşları (analitik; genelde 2) ---- std::vector cozumler; int seciliCozum = -1; // listede seçili/gidilen duruş (-1 = yok) // ---- Açı animasyonu (SIRALI tween: web gibi ÖNCE B, sonra C) ---- bool animVar = false; f32 bHedef = 0.0f, cHedef = 0.0f; f32 bBasla = 0.0f, cBasla = 0.0f; f32 animT = 0.0f; // geçen süre (saniye) f32 bSure = 1.0f; // B animasyon süresi (web 1000ms) f32 cGecikme = 0.75f; // C başlama gecikmesi (web delay 750ms) f32 cSure = 1.0f; // C animasyon süresi (web 1000ms) // ---- Kamera duruşu kalıcılığı (tanim->kameraAnahtar; oturumlar arası) ---- // Duruş DEĞİŞİRKEN yazılmaz (ayarYaz anında diske yazar → kare-başı IO yasak): // hareket durup kayitGecikme kadar sabit kalınca TEK sefer yazılır. Quatf sonYon{}; Vec3f sonOdak{}; f32 sonMesafe = 0.0f; f32 kayitBekle = 0.0f; bool kayitKirli = false; // diskte olandan farklı bir duruş var f32 kayitGecikme = 0.8f; // duruş bu kadar sabit kalınca yaz (saniye) // ---- Pencere-yerel görünüm/girdi durumu (belge_yonetici BelgeKaydi eşi) ---- u32 istG = 640, istY = 360; // Image alanının istediği hedef boyut f32 rectMinX = 0, rectMinY = 0; // Image sol-üst (mutlak ekran) bool hover = false; // imleç Image üstünde mi f32 sonEnBoy = 16.0f / 9.0f, sonG = 640, sonY = 360; f32 imlecX = 0, imlecY = 0; // pick imleci (Image-yerel piksel) int kameraKip = -1; // -1 yok, 0 döndür, 1 zoom, 2 pan bool kameraKullandi = false; f32 solBasX = 0, solBasY = 0; f32 sonrakiBoyutX = 0, sonrakiBoyutY = 0; // bir sonraki frame pencere boyutu (icerige oturtmak icin) }; // App-global örnekler (kafa başına bir tane; Meyers singleton kalıbı). KafaDurum& kafaDurum(KafaTip t); // Paneli görünür yap (menü komutu buna bağlanır). void kafaAc(KafaTip t); // Bu kafayı ayrı bir OS penceresinde (yeni fikocad.exe süreci, araç kipi) açar; // sahipHwnd doluysa yeni pencere ÇAĞIRANA Win32 owned-window olarak bağlanır // (bkz. kafa_penceresi.cpp kafaAyriPencerdeAc yorumu). Menüden çağrılır. void kafaAyriPencerdeAc(KafaTip t, void* sahipHwnd); // Komut satırından "--sahip=" oku (yeni süreç açılışında; belge_penceresi.cpp // FikoBelgePenceresi::pencereAyarKur kullanır). bool komutSatirindanSahip(std::string_view args, void*& out); // NOT: arka plan grid hücre boyu artık MERKEZÎ — Ayarlar → Pencere ("pencere.grid_adim", // ui::webSkinGridAdim). Pencere-yerel kafaGridAdimAl/Ata kaldırıldı. // Kare-başı (komut tamponu AÇILMADAN): HER İKİ kafa için lazy kur + parçaları yükle + // kamera yumuşat/kaydet + hedef boyutla + ImGui doku kaydını yenile. // bglm: DM bağlam menüsünden gönderilen bekleyen IJK hedefini (bglm.bekleyenIjkHedef) // tüketir — açık ilk kafanın I/J/K alanlarını doldurur (bkz. uygulama_baglam.hpp). void kafaGuncelle(ImGuiKatman& arayuz, VulkanBaglam& vulkan, f32 dt, const std::string& shaderDizin, UygulamaBaglam& bglm); // ImGui aşaması: her açık kafa için pencere + 3D Image (kamera jestleri) + kontroller. // bglm: "🎯 3d Seç" butonu bglm.ijkSecimBekliyor'u set eder (ana viewport // tıklamayı yakalar; bkz. belge_penceresi.cpp tık-seçim zinciri + uygulama_baglam.hpp). void kafaPencereCiz(VulkanBaglam& vulkan, UygulamaBaglam& bglm); // Komut tamponu aşaması: her açık kafanın mini-viewport sahnesini kendi hedefine kaydet. void kafaKaydet(VulkanBaglam& vulkan, BoruHatlari& hatlar, const IsikDurum& isikDurum, VkCommandBuffer kb, f32 zaman, int kare); } // namespace fiko