#include "ayar_kayitlari.hpp" #include // format yerine stringstream #include #include "arac_kayitlari.hpp" // araç kipi: tek araçlı lisansta otomatik açılış ayarı #include "arama_menu.hpp" #include "cam_simulasyon_penceresi.hpp" // camSimSahneGorselAl/Ata (cam.sim_sahne_gorsel) #include "malzeme_gpu.hpp" // malzemeDokuTavan/Anizotropi ayar bağları #include "makro_oneri.hpp" // menuOgrenmeAktif / komutOgrenmeSifirla — menü öğrenmesi #include "orkestra_kule.hpp" // orkestra* eşik köprüleri (orkestra.* kayıtları) #include "istakip_servis.hpp" // istakip* köprüleri (istakip.* kayıtları) #include "fiko/orkestra/task.hpp" // YerlestirmeAgirlik (orkestra.task_puan_* → kule) #include "ayar_kalici.hpp" #include "belge_penceresi.hpp" // aygitKaybindaYenidenBaslat #include "ayarlar_penceresi.hpp" #include "dinamik_komut_penceresi.hpp" #include "guncelleme_kontrol.hpp" #include "kesit_gizmo.hpp" // kesitGizmoAyar() — kesit karesi/profil tutamacı #include "geri_bildirim.hpp" #include "oto_kayit.hpp" // otoKayitAktif/Dakika/KusakSayisi ayar bağları #include "pafta_ciz.hpp" // teknik resim çizim eşikleri #include "pmi_ciz.hpp" // PMI overlay eşikleri #include "fiko/cekirdek/gecici.hpp" // merkezi geçici/önbellek dizini politikası #include "fiko/cekirdek/gorev.hpp" // açılış bakımı worker'da (GorevBaglam) #include "fiko/cekirdek/guncelleme.hpp" #include "fiko/ayar/ayar_sistemi.hpp" #include "fiko/cekirdek/cekirdek.hpp" #include "fiko/core/birim_bicim.hpp" // birim küsürat kayıt defteri (Ayarlar → Birimler) #include "fiko/dokum/dokum_kurulum.hpp" // Derece varsayılanları (kum döküm flask) #include "fiko/core/kare_istek.hpp" #include "fiko/sahne/olcum_sistemi.hpp" // birim değişince metinleriYenile #include "fiko/analiz/analiz_sistemi.hpp" #include "fiko/zeka/zeka_motoru.hpp" // dedektör eşik köprüsü (zeka.* kayıtları) #include "fiko/geometri/brep.hpp" // kaliciKimlikAcikMi/Ayarla — KYA kalıcı topolojik kimlik #include "fiko/geometri/kalite.hpp" #include "fiko/sahne/fark_hesap.hpp" // farkGpuKullan()/farkOtoToleransCarpan() — CAD Fark #include "fiko/sahne/isin_bvh.hpp" // bvhArkaplan() — BVH arka-plan kurulum ayarı #include "fiko/sahne/sahne.hpp" #include "fiko/render/orbit_kamera.hpp" #include "fiko/render/vulkan_aygit.hpp" // zamanAsimiTolerans (GPU kare gecikme toleransı) #include "fiko/cae/fem_hex.hpp" #include "fiko/dokum/voxelize.hpp" // voxel sınıflama paralel ayarları // FEM çözücü ayarları (cae.fem_*) #include "fiko/kinematik/mekanizma.hpp" // halkaOtoCoz (kapalı zincir otomatik çözüm) #include "fiko/parca/part_design_sistemi.hpp" // sketchOtoGizle (yutulan sketch gizleme) #include "fiko/platform/pencere.hpp" // surukleCiz (sürükleme sırasında çizim) #include "fiko/render/pencere_yuzeyi.hpp" // kurmaAralikMs (swapchain yeniden-kurma debounce) #include "fiko/render/secim_gpu.hpp" #include "fiko/gsd/gsd_registry.hpp" #include "fiko/parca/feature_registry.hpp" #include "fiko/ui/agac_simge_kayit.hpp" #include "fiko/ui/tema.hpp" #include "fiko/ui/web_skin.hpp" // webSkinGrid* — merkezî pencere ızgarası (Ayarlar → Pencere) #include "fiko/ui/pencere_cerceve.hpp" // pencereVarsayilanSkin* — global pencere görünümü #include "feature_penceresi.hpp" #include "urun_agaci_paneli.hpp" // kaydetAgac — FIKO_CEF'ten bağımsız, koşulsuz çağrılıyor #ifdef FIKO_CEF #include "yardim_cef.hpp" #endif #include "belge_ciz.hpp" // orbitLodGecikmeKare() — orbit LOD debounce ayarı #include "hizli3d_penceresi.hpp" #include "hover_karti.hpp" #include "isik_durum.hpp" #include "navigasyon_ghost.hpp" #include "vizyon_kupu.hpp" #include "secim_gorunum.hpp" #include "sketch_ui.hpp" #include "akilli_secim.hpp" // akıllı seçim toleransları #include "dogrudan_ayar.hpp" #include "fark_stil.hpp" // fikoUiAyar() — global UI ince ayarları #include "fark_tur.hpp" // farkTurSaniye() — CAD Fark sinematik tur ayarı #include "uygulama_baglam.hpp" namespace fiko { namespace { using ayar::AyarDeger; using ayar::AyarSistemi; using ayar::AyarTanim; using ayar::AyarTip; using ayar::dBool; using ayar::dF; using ayar::dInt; using ayar::dMetin; using ayar::dRenk; // Döküm varsayılan çözünürlüğü — DokumSimulasyonu::cozunurluk=40 ile birebir. u32 g_dokumCozunurluk = 40; bool g_dokumVoxelKirp = true; // voxel görselini parçanın ham AABB'sine kırp f32 g_dokumKapsamaEsik = 0.5f; // kafes/parça hacim oranı uyarı eşiği bool g_dokumSphDivergence = false; // DFSPH divergence çözücü (ölçüm: ince h'de patlatıyor) u32 g_dokumSphMaksPartikul = 400000; // SPH emitter havuzu tavanı (SphDolumAyar.maksPartikul) f64 g_dokumGirisKutlePay = 1.05; // "Uygula" kütle payı: kavite kütlesi × bu çarpan f64 g_dokumGirisUzakEsikH = 2.0; // giriş "kavite dışında" uyarı eşiği (× hücre boyu) f64 g_dokumCidarYuzdelik = 0.10; // "Cidarı ölç" alt yüzdeliği (0 = ham minimum) f64 g_dokumKapsamaSisme = 1.5; // kafes/parça hacim oranı ŞİŞME uyarı eşiği (0=kapalı) bool g_dokumPorOtoEsik = true; // porozite izo-eşiğini veriden türet (ilk kurulumda) f64 g_dokumPorYuzdelik = 0.90; // oto eşik yüzdeliği (0.90 = en kötü %10 vurgulanır) // Derece (kum döküm flask) yeni sim varsayılanları — dokum::Derece ile birebir. bool g_dokumDereceGoster = true; f64 g_dokumDereceKumPay = 50.0, g_dokumDereceUstPay = 60.0, g_dokumDereceAltPay = 60.0; f64 g_dokumDereceDuvar = 18.0; bool g_dokumDereceTekParca = false; // tek çerçeveli derece (çevirmeli kalıplama) f64 g_dokumDereceKumSaydamlik = 0.18; // kum bloğu saydamlığı (çerçeve 0.45 kalır) f64 g_dokumKumYogunluk = 1550.0; // kalıp kumu yoğunluğu [kg/m³] (yeşil kum) bool g_dokumPartikulKaydet = true; // SPH karesinde partikül konumlarını sakla u32 g_dokumPartikulAltOrnek = 1; // kayıtta n'de bir partikül f32 g_dokumPartikulYaricapOran = 0.30f; // blob yarıçapı = hücre boyu × oran u32 g_dokumPartikulCizAltOrnek = 1; // çizimde n'de bir partikül // Strafor montaj: yeni panel açılışındaki varsayılan hedef parça ölçüsü + geçici öncelik. f64 g_straforHedefEn = 2500, g_straforHedefBoy = 1500, g_straforHedefYuk = 300; bool g_straforGeciciOncelik = false; u32 g_straforVaryant = 40; // gösterilecek montaj seçeneği (varyant) sayısı bool g_straforOffcutNesting = true; // giyotin artık yeniden kullanım planları da üret f64 g_straforIscilikAgirlik = 2.0; // sıralama işçilik önceliği (0=malzeme, büyük=az yapıştırma) // APT (.FikoApt/.apt) ithalinde yolu sahneye çizme; onun yerine simülasyon // penceresinde oynat (varsayılan açık). Kapalı = eski davranış (neon-cyan yol düğümü sahnede). bool g_aptIthalSim = true; bool g_aptAktiviteAyir = true; f64 g_aptYayTolerans = 0.01; // Zekâ Motoru: komut kapısı + dedektör eşik gölgeleri (.al okuması buradan; // dedektörde getter yok — Dedektor::esikAyarla tek yönlü köprüdür). bool g_zekaAktif = true; bool g_zekaHesapAsync = true; // zeka.hesap_async — ağır OCCT okumaları worker'da u64 g_orkestraYanitsizMs = 5000; // orkestra.yanitsiz_esik_ms — node Yanıtsız eşiği u64 g_orkestraOfflineMs = 10000; // orkestra.offline_esik_ms — node Çevrimdışı eşiği u64 g_orkestraTazelemeMs = 500; // orkestra.tazele_ms — kule defter tazeleme aralığı bool g_orkestraLanKesif = false; // orkestra.lan_kesif — UDP beacon (varsayılan KAPALI) i64 g_orkestraLanPort = 47810; // orkestra.lan_port — beacon portu u64 g_orkestraBeaconSn = 3; // orkestra.beacon_sn — beacon yayın aralığı u64 g_orkestraMetrikMs = 1000; // orkestra.metrik_aralik_ms — kaynak nabzı aralığı i64 g_orkestraTcpPort = 47811; // orkestra.tcp_port — çerçeve kanalı dinleme portu i64 g_orkestraTcpMaksBag = 16; // orkestra.tcp_maks_baglanti — eşzamanlı kanal tavanı i64 g_orkestraTcpMaksGovdeMB = 4; // orkestra.tcp_maks_govde_mb — çerçeve gövde tavanı u64 g_orkestraEslesmeTtlSn = 120; // orkestra.eslesme_ttl_sn — bekleyen istek zaman aşımı i64 g_orkestraPuanCpu = 50; // orkestra.task_puan_cpu — CPU boşluğu ağırlığı (%) i64 g_orkestraPuanTask = 40; // orkestra.task_puan_task — kuyruk boşluğu ağırlığı (%) i64 g_orkestraPuanBellek = 10; // orkestra.task_puan_bellek — RAM uygunluk ağırlığı (%) i64 g_orkestraPuanDoyum = 8; // orkestra.task_puan_doyum — tam-dolu aktif task sayısı i64 g_orkestraTransferParcaKB = 256; // orkestra.transfer_parca_kb — dosya transfer parça boyu bool g_istakipKral = false; // istakip.kral — bu makine İş Takip kralı i64 g_istakipPort = 47820; // istakip.port — kral dinleme portu std::string g_istakipKralAdres; // istakip.kral_adres — istemci hedefi "ip:port" std::string g_istakipMongoUri = "mongodb://localhost:27017/fiko_istakip"; // istakip.mongo_uri bool g_istakipIstemciYazabilir = true; // istakip.istemci_yazabilir — kapalı=salt kral yazar bool g_istakipKimlik = false; // istakip.kimlik_dogrulama — TOFU kanıt zorunlu i64 g_istakipSnapshotParca = 512; // istakip.snapshot_parca — snapshot dilim boyu (kayıt) f64 g_zekaFilletTegetTol = 5.0; // zeka.fillet.teget_aci_tol f64 g_zekaFilletYaricapTol = 1.0; // zeka.fillet.yaricap_uyum_tol bool g_ozmo_kafa_ayrilik_proses = false; // Ozmo Kafa ayr� bir pencere olarak a��lmal� m�? // Ozmo Kafa ayr srete alsn m? bool g_diagonal_kafa_ayrilik_proses = false; // Diagonal Kafa ayr� bir pencere olarak a��lmal� m�? // Diagonal Kafa ayr srete alsn m?? f64 g_zekaCepSlotOran = 3.0; // zeka.cep.slot_oran f64 g_zekaCepBossAlanOran = 0.5; // zeka.cep.boss_alan_oran f64 g_zekaPahSeritOran = 0.25; // zeka.pah.serit_oran // Tema kalıcılığı ZATEN main.cpp "tema" anahtarıyla yapılır (her kaynaklı değişimi // yakalayan izleyici). Çift doğruluk kaynağı olmasın diye bu kimlik köprü/yüklemeden // hariç tutulur — ayar yalnız canlı durumu sürer. constexpr const char* TEMA_KIMLIK = "gorunum.tema"; // Bir yönsel ışığın 4 ayarını (aktif/şiddet/renk/headlight) kaydeder. void isikAyarlari(AyarSistemi& s, const char* onek, YonselIsik* y, const YonselIsik& vars, const char* etiketOnek) { const std::string k(onek); s.ayarKaydet({.kimlik = k + "_aktif", .kategori = "Aydınlatma", .ad = std::string(etiketOnek) + " açık", .aciklama = "Yönsel ışığı aç/kapa.", .tip = AyarTip::Bool, .varsayilan = dBool(vars.aktif), .al = [y] { return dBool(y->aktif); }, .ata = [y](const AyarDeger& d) { y->aktif = d.b; }}); s.ayarKaydet({.kimlik = k + "_siddet", .kategori = "Aydınlatma", .ad = std::string(etiketOnek) + " şiddeti", .aciklama = "Işık parlaklık çarpanı.", .tip = AyarTip::F32, .varsayilan = dF(vars.siddet), .min = 0, .maks = 3, .al = [y] { return dF(y->siddet); }, .ata = [y](const AyarDeger& d) { y->siddet = (f32)d.f; }}); s.ayarKaydet({.kimlik = k + "_renk", .kategori = "Aydınlatma", .ad = std::string(etiketOnek) + " rengi", .aciklama = "Işık rengi (RGB).", .tip = AyarTip::Renk, .varsayilan = dRenk(vars.renk), .al = [y] { return dRenk(y->renk); }, .ata = [y](const AyarDeger& d) { y->renk = d.renk; }}); s.ayarKaydet({.kimlik = k + "_kamera_takip", .kategori = "Aydınlatma", .ad = std::string(etiketOnek) + " kamerayı takip", .aciklama = "Headlight: ışık yönü kameradan türetilir.", .tip = AyarTip::Bool, .varsayilan = dBool(vars.kameraTakip), .al = [y] { return dBool(y->kameraTakip); }, .ata = [y](const AyarDeger& d) { y->kameraTakip = d.b; }}); } // ---- Domain-bazlı ayar kaydı (ayarlarKaydet god-function'ı modülerleştirildi) ---- void kaydetKesit(AyarSistemi& s, UygulamaBaglam& b) { analiz::AnalizSistemi* an = &b.analizSis; s.ayarKaydet({.kimlik = "kesit.gpu_kapak", .kategori = "Kesit", .ad = "GPU kesit kapağı", .aciklama = "Düz (analiz-renksiz) kapaklar GPU'da anlık çizilir; pahalı OCCT " "boolean+remesh atlanır. Kapalı → tüm kapaklar OCCT (yavaş ama " "gövde-başına malzeme renkli).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [an] { return dBool(an->gpuKapak); }, .ata = [an](const AyarDeger& d) { an->gpuKapak = d.b; for (u32 kk : an->kesitler()) an->kesitGuncelle(kk); }}); static const char* kipAd[4] = {"Kapak yok", "Kapalı (opak)", "Yarı saydam", "Saydam"}; s.ayarKaydet({.kimlik = "kesit.kapak_kip", .kategori = "Kesit", .ad = "Kesit kapağı", .aciklama = "Kesilen içi dolu göster: kapak yok, opak, yarı saydam veya saydam.", .tip = AyarTip::Secenek, .varsayilan = dMetin("Kapalı (opak)"), .secenekler = {kipAd[0], kipAd[1], kipAd[2], kipAd[3]}, .al = [an] { return dMetin(kipAd[(int)an->kapakKip]); }, .ata = [an](const AyarDeger& d) { for (int i = 0; i < 4; ++i) if (d.metin == kipAd[i]) an->kapakKip = (analiz::AnalizSistemi::KapakKip)i; for (u32 kk : an->kesitler()) an->kesitGuncelle(kk); }}); s.ayarKaydet({.kimlik = "kesit.profil_kalin", .kategori = "Kesit", .ad = "Kesit profili kalın çizgi", .aciklama = "Kesit eğrisi kalın vurgu kalemiyle (4px) çizilir — sahnede " "belirgin (keskin kenar çizgileriyle aynı kalem). Değişiklik " "kesitin bir sonraki güncellemesinde uygulanır.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [an] { return dBool(an->kesitProfilKalin); }, .ata = [an](const AyarDeger& d) { an->kesitProfilKalin = d.b; for (u32 kk : an->kesitler()) an->kesitGuncelle(kk); }}); s.ayarKaydet({.kimlik = "kesit.surukle_kapak_canli", .kategori = "Kesit", .ad = "Sürüklemede kapak canlı hesap", .aciklama = "Kesit sürüklenirken OCCT kapak da her adımda yeniden hesaplanır " "(ölçüldü: kapak 17.9 ms vs profil 3.2 ms — büyük modelde takılma). " "Kapalı (varsayılan): sürüklemede yalnız profil, kapak bırakışta.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [an] { return dBool(an->kesitSurukleKapakCanli); }, .ata = [an](const AyarDeger& d) { an->kesitSurukleKapakCanli = d.b; }}); s.ayarKaydet({.kimlik = "kesit.surukle_guncelleme_ms", .kategori = "Kesit", .ad = "Sürükleme ağır güncelleme aralığı (ms)", .aciklama = "Kesit sürüklerken B-Rep profil (ve açıksa kapak) bu aralıkla " "yeniden hesaplanır. Clip anlıktır; bu yalnız eğri/kapak tazeleme " "sıklığı. Küçük değer = daha canlı, daha çok CPU.", .tip = AyarTip::F32, .varsayilan = dF(120.0), .min = 30.0, .maks = 1000.0, .al = [an] { return dF(an->kesitSurukleMs); }, .ata = [an](const AyarDeger& d) { an->kesitSurukleMs = (f32)d.f; }}); s.ayarKaydet({.kimlik = "kesit.gizmo_dolgu", .kategori = "Kesit", .ad = "Kesit karesi dolgulu", .aciklama = "Kesit gizmosunun karesi yarı saydam dolguyla çizilir. Kapalı " "(varsayılan) = yalnız çerçeve → kare modeli soluklaştırmaz.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(kesitGizmoAyar().dolgu); }, .ata = [](const AyarDeger& d) { kesitGizmoAyar().dolgu = d.b; }}); s.ayarKaydet({.kimlik = "kesit.profil_tut", .kategori = "Kesit", .ad = "Kesişim profilinden sürükle", .aciklama = "Kesitin model üstünde çizdiği eğriden tutup sürükleyerek düzlemi " "kaydır (merkez okuna nişan almak gerekmez). Kapalı = yalnız ok " "tutamacı.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(kesitGizmoAyar().profilTut); }, .ata = [](const AyarDeger& d) { kesitGizmoAyar().profilTut = d.b; }}); s.ayarKaydet({.kimlik = "kesit.profil_tut_piksel", .kategori = "Kesit", .ad = "Profil yakalama toleransı (px)", .aciklama = "Kesişim profilini kaç piksel yakınından tutabilirsin.", .tip = AyarTip::F32, .varsayilan = dF(7.0), .min = 2.0, .maks = 20.0, .al = [] { return dF(kesitGizmoAyar().profilTutPiksel); }, .ata = [](const AyarDeger& d) { kesitGizmoAyar().profilTutPiksel = (f32)d.f; }}); s.ayarKaydet({.kimlik = "kesit.profil_tut_maks_segment", .kategori = "Kesit", .ad = "Profil taramasında en çok segment", .aciklama = "Profil hover testi her kare koşar; dev modelde taramayı sınırlar " "(0 = sınırsız). Üstündeki segmentlerden tutulamaz.", .tip = AyarTip::Int, .varsayilan = dInt(4000), .min = 0, .maks = 200000, .al = [] { return dInt(kesitGizmoAyar().profilTutMaksSegment); }, .ata = [](const AyarDeger& d) { kesitGizmoAyar().profilTutMaksSegment = (int)d.i; }}); } void kaydetUndercut(AyarSistemi& s, UygulamaBaglam& b) { analiz::AnalizSistemi* an = &b.analizSis; // Undercut per-yüz alanı hesapla()'da üretilir; bu ayarlar onun GİRDİSİ → // değişince YENİDEN HESAPLA. Aksi halde ayar hiçbir şey yapmaz (kullanıcı // "adımı küçülttüm, değişmedi" der — yaşandı). const auto yenidenHesapla = [an] { for (u32 k : an->hepsi()) if (auto* a = an->bul(k); a && a->tip() == analiz::AnalizTip::Undercut) { a->bayatAyarla(true); an->hesapla(k); } }; s.ayarKaydet({.kimlik = "analiz.undercut_gorunurluk", .kategori = "Analiz", .ad = "Undercut: görünürlük ile karar ver", .aciklama = "Açık: çekim yönünde gölge (derinlik) haritası — önünde başka " "yüzey olan nokta erişilemez sayılır (kapalı/dik delik bütünüyle " "kırmızı). Web sürümüyle aynı yol. Kapalı: eski saf normal·yön " "yolu (dik deliği yarı yeşil yarı kırmızı boyar).", .tip = AyarTip::Bool, .varsayilan = dBool(analiz::undercutGorunurluk()), .al = [] { return dBool(analiz::undercutGorunurluk()); }, .ata = [yenidenHesapla](const AyarDeger& d) { analiz::undercutGorunurlukAyarla(d.b); yenidenHesapla(); }}); static const char* kipAd[3] = {analiz::undercutKipAdi(analiz::UndercutKip::Yuz), analiz::undercutKipAdi(analiz::UndercutKip::Golge), analiz::undercutKipAdi(analiz::UndercutKip::Hibrit)}; // ⚠️ YUZ ve HIBRIT KIPLERI GECICI OLARAK DEVRE DISI (2026-07-15, kullanici karari). // Ikisi de `undercutGolgeMesh` exact boolean'ina dayaniyor; olculdu: 20 kismi yuzun // 5'inde `basari=0` donuyor (OCCT BOP kararsizligi — ayna ikizi ord=38/39 birebir ayni // geometri, biri calisiyor otekinde Common(govde,G) bos geliyor). Sonuc: Yuz kipi // parcanin %81.8'ini kirmiziya boyuyor (gercek golge %52.6), Hibrit overlay'i %24 eksik. // Golge kipi DOGRU calisiyor (kullanici dogruladi) → tek secenek o. // Yeniden acmadan once: [[fikatia-undercut-gorunurluk]] — elenen cozumler orada // (orientation notrleme=etkisiz, fuzzy tolerans=daha kotu). Enum/kod BIREBIR duruyor, // geri acmak = seceneklere kipAd[0]/kipAd[2] eklemek. s.ayarKaydet({.kimlik = "analiz.undercut_kip", .kategori = "Analiz", .ad = "Undercut çizim kipi", .aciklama = "Gölge: per-fragment gölge haritası — kısmi gölgenin gerçek şekli " "görünür. ŞU AN TEK ETKİN KİP. (Yüz ve Hibrit kipleri exact " "boolean'daki bir hata nedeniyle geçici olarak kapatıldı: kısmi " "yüzleri fazla/eksik boyuyorlardı.)", .tip = AyarTip::Secenek, .varsayilan = dMetin(kipAd[1]), .secenekler = {kipAd[1]}, .al = [] { return dMetin(analiz::undercutKipAdi(analiz::undercutKip())); }, .ata = [yenidenHesapla](const AyarDeger& d) { // Yalniz Golge kabul edilir. Eski ayar dosyasinda "Yüz"/"Hibrit" yazsa // bile sessizce Golge'ye duser (bozuk kipe geri donulmesin). (void)d; analiz::undercutKipAyarla(analiz::UndercutKip::Golge); yenidenHesapla(); // Golge kipinde alan üretilmez → kip değişimi girdi }}); s.ayarKaydet({.kimlik = "analiz.undercut_ornek_adim", .kategori = "Analiz", .ad = "Undercut örnek adımı (mm)", .aciklama = "⚠️ ŞU AN ETKİSİZ — yalnız kapalı olan Yüz/Hibrit kiplerinde " "kullanılır (Gölge kipi örnekleme yapmaz). Yüz örnekleme sıklığı: " "saptanabilecek EN İNCE gölgeyi belirler. 0 = otomatik (gövde " "köşegeni/150). Küçültmek hesabı pahalılaştırır.", .tip = AyarTip::F32, .varsayilan = dF(analiz::undercutOrnekAdim()), .min = 0.0f, .maks = 50.0f, .al = [] { return dF(analiz::undercutOrnekAdim()); }, .ata = [yenidenHesapla](const AyarDeger& d) { analiz::undercutOrnekAdimAyarla(d.f); yenidenHesapla(); }}); s.ayarKaydet({.kimlik = "analiz.undercut_izgara_maks", .kategori = "Analiz", .ad = "Undercut örnek tavanı (eksen başına)", .aciklama = "⚠️ ŞU AN ETKİSİZ — yalnız kapalı olan Yüz/Hibrit kiplerinde " "kullanılır. Bir yüzden atılacak azami ışın = tavan². Büyük " "yüzlerde hesabı sınırlar. Analiz yavaşsa düşürün.", .tip = AyarTip::Int, .varsayilan = dInt((i64)analiz::undercutIzgaraMaks()), .min = 2, .maks = 128, .al = [] { return dInt((i64)analiz::undercutIzgaraMaks()); }, .ata = [yenidenHesapla](const AyarDeger& d) { analiz::undercutIzgaraMaksAyarla((u32)d.i); yenidenHesapla(); }}); s.ayarKaydet({.kimlik = "analiz.golge_cozunurluk", .kategori = "Analiz", .ad = "Undercut gölge haritası çözünürlüğü", .aciklama = "Çekim yönündeki derinlik haritasının kare çözünürlüğü. Düşük → " "merdivenli gölge kenarı. VRAM: 4096→64 MB, 8192→256 MB, " "16384→1 GB. Frustum analiz edilen gövdeye daraltıldığı için " "4096 çoğu parçada web'in 2048'inden çok daha keskindir. " "⚠️ DEĞİŞTİRMEK RİSKLİ: hedef yeniden kurulumu kare kaydı " "içinde olur (device idle) — undercut açıkken değiştirmeyin.", .tip = AyarTip::Int, .varsayilan = dInt((i64)analiz::golgeCozunurluk()), .min = 256, .maks = 16384, .al = [] { return dInt((i64)analiz::golgeCozunurluk()); }, .ata = [](const AyarDeger& d) { analiz::golgeCozunurlukAyarla((u32)d.i); }}); s.ayarKaydet({.kimlik = "analiz.golge_esik", .kategori = "Analiz", .ad = "Undercut gölge derinlik eşiği", .aciklama = "Derinlik karşılaştırma toleransı. Çok küçük → yüzeyde benekli " "kırmızı (gölge akne); çok büyük → ince undercut'lar kaçar.", .tip = AyarTip::F32, .varsayilan = dF(analiz::golgeEsik()), .min = 1e-6f, .maks = 1e-2f, .al = [] { return dF(analiz::golgeEsik()); }, .ata = [](const AyarDeger& d) { analiz::golgeEsikAyarla(d.f); }}); // Radius per-yüz alanı da hesapla()'da üretilir → bu ayar onun GİRDİSİ, değişince // yeniden hesapla (undercut'taki ile aynı gerekçe). const auto radiusYenidenHesapla = [an] { for (u32 k : an->hepsi()) if (auto* a = an->bul(k); a && a->tip() == analiz::AnalizTip::Radius) { a->bayatAyarla(true); an->hesapla(k); } }; s.ayarKaydet({.kimlik = "analiz.radius_serbest_kurvatur", .kategori = "Analiz", .ad = "Radius: serbest yüzeylerde eğrilikten yarıçap", .aciklama = "Açık: B-spline ve koni yüzlerde analitik yarıçap yoktur → asal " "eğrilikten R = 1/max(|kMin|,|kMaks|) hesaplanır (BRepLProp — " "mesh yoğunluğundan ve zoom'dan bağımsız, kalibrasyon gerekmez). " "Kapalı: o yüzler nötr kalır (yalnız silindir/küre/torus renklenir). " "Düzlem her iki durumda da nötrdür (eğrilik 0 → R sonsuz).", .tip = AyarTip::Bool, .varsayilan = dBool(analiz::radiusSerbestKurvatur()), .al = [] { return dBool(analiz::radiusSerbestKurvatur()); }, .ata = [radiusYenidenHesapla](const AyarDeger& d) { analiz::radiusSerbestKurvaturAyarla(d.b); radiusYenidenHesapla(); }}); // Kalınlık ayarları da hesabın GİRDİSİ → değişince ilgili analizler yeniden koşar. const auto kalinlikYenidenHesapla = [an] { for (u32 k : an->hepsi()) if (auto* a = an->bul(k); a && a->tip() == analiz::AnalizTip::Kalinlik) { a->bayatAyarla(true); an->hesapla(k); } }; s.ayarKaydet({.kimlik = "analiz.kalinlik_yuz_min", .kategori = "Analiz", .ad = "Kalınlık: yüz başına en ince değer", .aciklama = "Açık: bir yüzün rengi/raporu o yüzdeki EN İNCE cidardır " "(en-kötü-durum — et kalınlığı analizinin amacı budur). " "Kapalı: yüz örneklerinin ORTALAMASI (eski davranış); değişken " "cidarda en ince yer maskelenir — 1→10 mm kamada ortalama " "5.5 mm derken gerçek en ince cidar 1.0 mm'dir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(analiz::kalinlikYuzMin()); }, .ata = [kalinlikYenidenHesapla](const AyarDeger& d) { analiz::kalinlikYuzMinAyarla(d.b); kalinlikYenidenHesapla(); }}); s.ayarKaydet({.kimlik = "analiz.kalinlik_perfragment", .kategori = "Analiz", .ad = "Kalınlık: per-fragment GPU ışın (gerçek ısı haritası)", .aciklama = "Açık: kalınlık HER PİKSEL için, o noktanın yüzey normali " "boyunca içeri ışın atılarak GPU'da ölçülür (dünya-uzayı BVH) " "→ sonuç mesh üçgenlemesinden tamamen bağımsızdır. Kapalı: " "per-vertex alan — büyük/delikli yüzlerde köşelerden yayılan " "yıldız/üçgen deseni görünür. Yalnız 3B boyamayı etkiler; " "rapordaki sayılar her iki durumda da aynı kaynaktan gelir. " "Aynı anda TEK gövde per-fragment boyanır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(analiz::kalinlikPerFragment()); }, .ata = [](const AyarDeger& d) { analiz::kalinlikPerFragmentAyarla(d.b); }}); s.ayarKaydet({.kimlik = "analiz.kalinlik_pervertex", .kategori = "Analiz", .ad = "Kalınlık: nokta ısı haritası (per-vertex)", .aciklama = "Açık: kalınlık her mesh noktası için ayrı boyanır → duvar " "boyunca pürüzsüz ısı haritası; iç ve dış yüzey noktasal " "gerçek kalınlığıyla renklenir (GPU wall.comp zaten nokta " "başına ölçüyordu, değeri yüz ortalamasına indirip atıyorduk). " "Kapalı: yüz başına tek renk (eski davranış). CPU yedek " "yolunda her hâlükârda yüz başınadır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(analiz::kalinlikPerVertex()); }, .ata = [kalinlikYenidenHesapla](const AyarDeger& d) { analiz::kalinlikPerVertexAyarla(d.b); kalinlikYenidenHesapla(); }}); s.ayarKaydet({.kimlik = "analiz.kalinlik_izgara", .kategori = "Analiz", .ad = "Kalınlık örnekleme ızgarası (eksen başına)", .aciklama = "Her yüz kendi UV uzayında n×n hücreye bölünür, hücre " "MERKEZLERİNDEN iç ışın atılır (köşe örneklemesi komşu yüzü " "sıyırıp ıskalıyordu). Büyütmek doğruluğu artırır, maliyet " "kareyle büyür (n=8 → yüz başına ≤64 ışın).", .tip = AyarTip::Int, .varsayilan = dInt(8), .min = 2, .maks = 64, .al = [] { return dInt((i64)analiz::kalinlikIzgara()); }, .ata = [kalinlikYenidenHesapla](const AyarDeger& d) { analiz::kalinlikIzgaraAyarla((u32)d.i); kalinlikYenidenHesapla(); }}); // Keskin Kenar: yeni analiz bu eşikle doğar; mevcut analiz eşiğini panelden yönetir. s.ayarKaydet({.kimlik = "analiz.keskin_kenar_esik", .kategori = "Analiz", .ad = "Keskin kenar eşiği (°)", .aciklama = "Yeni Keskin Kenar analizinin başlangıç dihedral eşiği: iki " "komşu yüz arasındaki açı bunun üstündeyse kenar keskin sayılır " "(dışbükey kırmızı, içbükey mavi çizilir).", .tip = AyarTip::F32, .varsayilan = dF(30.0), .min = 1.0, .maks = 179.0, .al = [an] { return dF(an->keskinVarsayilanEsikDeg); }, .ata = [an](const AyarDeger& d) { an->keskinVarsayilanEsikDeg = (f32)d.f; }}); s.ayarKaydet({.kimlik = "analiz.hesap_async", .kategori = "Analiz", .ad = "Analiz hesabı arka planda (deneysel)", .aciklama = "Ağır analiz hesapları worker thread'de: Keskin Kenar, Süreklilik, " "Et Kalınlığı (CPU yolu) ve Undercut exact görünürlük (ölçüldü: " "546-1300 ms) — dev modelde UI kilitlenmez. Undercut'ta görsel önce " "gölge/analitik gelir, exact sonuç arkadan keskinleşir. Kapalı " "(varsayılan): eski senkron yol birebir.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [an] { return dBool(an->hesapAsync); }, .ata = [an](const AyarDeger& d) { an->hesapAsync = d.b; }}); s.ayarKaydet({.kimlik = "analiz.keskin_oneri_pah", .kategori = "Analiz", .ad = "Keskin kenar öneri pah boyu (mm)", .aciklama = "Analiz panelindeki \"dışbükeye pah\" önerisinin varsayılan C " "mesafesi. Panelden anlık da değiştirilebilir.", .tip = AyarTip::F32, .varsayilan = dF(2.0), .min = 0.1, .maks = 50.0, .al = [an] { return dF(an->keskinOneriPah); }, .ata = [an](const AyarDeger& d) { an->keskinOneriPah = (f32)d.f; }}); s.ayarKaydet({.kimlik = "analiz.keskin_oneri_fillet", .kategori = "Analiz", .ad = "Keskin kenar öneri fillet yarıçapı (mm)", .aciklama = "Analiz panelindeki \"içbükeye fillet\" önerisinin varsayılan R " "yarıçapı. Panelden anlık da değiştirilebilir.", .tip = AyarTip::F32, .varsayilan = dF(3.0), .min = 0.1, .maks = 50.0, .al = [an] { return dF(an->keskinOneriFillet); }, .ata = [an](const AyarDeger& d) { an->keskinOneriFillet = (f32)d.f; }}); s.ayarKaydet({.kimlik = "analiz.keskin_kenar_kalin", .kategori = "Analiz", .ad = "Keskin kenar kalın çizgi", .aciklama = "Keskin kenar çizgileri kalın vurgu kalemiyle (4px) çizilir — " "sahnede belirgin. Kapalı: standart ince kenar (1.6px).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [an] { return dBool(an->keskinKalin); }, .ata = [an](const AyarDeger& d) { an->keskinKalin = d.b; }}); s.ayarKaydet({.kimlik = "analiz.keskin_kenar_ustte", .kategori = "Analiz", .ad = "Keskin kenar X-ray (hep üstte)", .aciklama = "Keskin kenar çizgileri derinlik testi olmadan çizilir: modelin " "arkasında kalan kenarlar da görünür (tüm keskin kenarları tek " "bakışta gör). Kapalı: kenarlar gövde tarafından örtülür.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [an] { return dBool(an->keskinUstte); }, .ata = [an](const AyarDeger& d) { an->keskinUstte = d.b; }}); } // ---- Zekâ Motoru (Geometri Zekâ Grafı) — eşikler Dedektor::esikAyarla köprüsüyle // atanır (dedektör başlıkları uygulamaya sızmaz); değişiklik bir SONRAKİ Zekâ // Analizi'nde etkilidir (graf istekte yeniden kurulur). ---- void kaydetZeka(AyarSistemi& s, UygulamaBaglam& b) { zeka::ZekaMotoru* z = &b.zekaSis; s.ayarKaydet({.kimlik = "zeka.aktif", .kategori = "Zekâ", .ad = "Zekâ Motoru", .aciklama = "Geometri Zekâ Motoru: gövde sağ-tık → Zekâ Analizi ile feature " "tanıma (delik/cep/fillet/pah/pattern/simetri). Hesap yalnız " "istekte koşar; kapalıyken komut uyarı verir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_zekaAktif); }, .ata = [](const AyarDeger& d) { g_zekaAktif = d.b; }}); s.ayarKaydet({.kimlik = "zeka.hesap_async", .kategori = "Zekâ", .ad = "Arka planda hesapla", .aciklama = "Zekâ Analizi'nin ağır OCCT okumaları worker thread'de gövdenin " "derin kopyası üzerinde koşar — arayüz kilitlenmez. Kapalı: " "eski senkron yol (hesap bitene dek beklenir).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_zekaHesapAsync); }, .ata = [](const AyarDeger& d) { g_zekaHesapAsync = d.b; }}); // ── Fiko Orchestrator (kule) eşikleri ───────────────────────────────────── s.ayarKaydet({.kimlik = "orkestra.yanitsiz_esik_ms", .kategori = "Orkestra", .ad = "Node yanıtsız eşiği (ms)", .aciklama = "Bir node'un heartbeat/beacon sessizliği bu süreyi aşarsa " "durumu Yanıtsız gösterilir.", .tip = AyarTip::Int, .varsayilan = dInt(5000), .min = 500, .maks = 600000, .al = [] { return dInt((i64)g_orkestraYanitsizMs); }, .ata = [](const AyarDeger& d) { g_orkestraYanitsizMs = (u64)d.i; }}); s.ayarKaydet({.kimlik = "orkestra.offline_esik_ms", .kategori = "Orkestra", .ad = "Node çevrimdışı eşiği (ms)", .aciklama = "Sessizlik bu süreyi aşarsa node Çevrimdışı sayılır " "(kayıttan silinmez, kart gri kalır).", .tip = AyarTip::Int, .varsayilan = dInt(10000), .min = 1000, .maks = 3600000, .al = [] { return dInt((i64)g_orkestraOfflineMs); }, .ata = [](const AyarDeger& d) { g_orkestraOfflineMs = (u64)d.i; }}); s.ayarKaydet({.kimlik = "orkestra.tazele_ms", .kategori = "Orkestra", .ad = "Kule tazeleme aralığı (ms)", .aciklama = "Orchestrator paneli açıkken yerel node ilanı + durum " "türetme bu aralıkla çalışır (panel kapalıyken hiç çalışmaz).", .tip = AyarTip::Int, .varsayilan = dInt(500), .min = 100, .maks = 10000, .al = [] { return dInt((i64)g_orkestraTazelemeMs); }, .ata = [](const AyarDeger& d) { g_orkestraTazelemeMs = (u64)d.i; }}); s.ayarKaydet({.kimlik = "orkestra.lan_kesif", .kategori = "Orkestra", .ad = "LAN keşfi (beacon)", .aciklama = "Yerel ağdaki FikoCAD makinelerini UDP beacon ile keşfet. " "KAPALI: hiç soket açılmaz, ağa hiçbir şey yayınlanmaz " "(varsayılan). Açık: Orchestrator paneli açıkken beacon " "yayınlanır ve komşu node'lar listelenir.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(g_orkestraLanKesif); }, .ata = [](const AyarDeger& d) { g_orkestraLanKesif = d.b; }}); s.ayarKaydet({.kimlik = "orkestra.lan_port", .kategori = "Orkestra", .ad = "LAN keşif portu", .aciklama = "Beacon UDP portu — ağdaki tüm FikoCAD makinelerinde aynı " "olmalı.", .tip = AyarTip::Int, .varsayilan = dInt(47810), .min = 1024, .maks = 65535, .al = [] { return dInt(g_orkestraLanPort); }, .ata = [](const AyarDeger& d) { g_orkestraLanPort = d.i; }}); s.ayarKaydet({.kimlik = "orkestra.beacon_sn", .kategori = "Orkestra", .ad = "Beacon aralığı (sn)", .aciklama = "Kendi node ilanının yayın sıklığı. Çevrimdışı eşiği bunun " "en az 2-3 katı olmalı.", .tip = AyarTip::Int, .varsayilan = dInt(3), .min = 1, .maks = 60, .al = [] { return dInt((i64)g_orkestraBeaconSn); }, .ata = [](const AyarDeger& d) { g_orkestraBeaconSn = (u64)d.i; }}); s.ayarKaydet({.kimlik = "orkestra.metrik_aralik_ms", .kategori = "Orkestra", .ad = "Kaynak nabzı aralığı (ms)", .aciklama = "Node kartındaki CPU/RAM/VRAM/disk ölçümlerinin tazelenme " "sıklığı (yalnız Orchestrator paneli açıkken çalışır).", .tip = AyarTip::Int, .varsayilan = dInt(1000), .min = 250, .maks = 60000, .al = [] { return dInt((i64)g_orkestraMetrikMs); }, .ata = [](const AyarDeger& d) { g_orkestraMetrikMs = (u64)d.i; }}); s.ayarKaydet({.kimlik = "orkestra.tcp_port", .kategori = "Orkestra", .ad = "Çerçeve kanalı portu (TCP)", .aciklama = "Node'lar arası komut/olay kanalının dinleme portu. Makinede " "ilk açan fikocad dinler (gömülü ajan).", .tip = AyarTip::Int, .varsayilan = dInt(47811), .min = 1024, .maks = 65535, .al = [] { return dInt(g_orkestraTcpPort); }, .ata = [](const AyarDeger& d) { g_orkestraTcpPort = d.i; }}); s.ayarKaydet({.kimlik = "orkestra.tcp_maks_baglanti", .kategori = "Orkestra", .ad = "Eşzamanlı kanal tavanı", .aciklama = "Aynı anda kabul edilen TCP kanal sayısı — fazlası bekletilir " "(kaynak tüketimi sınırı).", .tip = AyarTip::Int, .varsayilan = dInt(16), .min = 1, .maks = 128, .al = [] { return dInt(g_orkestraTcpMaksBag); }, .ata = [](const AyarDeger& d) { g_orkestraTcpMaksBag = d.i; }}); s.ayarKaydet({.kimlik = "orkestra.tcp_maks_govde_mb", .kategori = "Orkestra", .ad = "Çerçeve gövde tavanı (MB)", .aciklama = "Tek çerçevenin izin verilen en büyük gövdesi — aşan akış " "bozuk sayılır ve bağlantı kesilir (bellek koruması).", .tip = AyarTip::Int, .varsayilan = dInt(4), .min = 1, .maks = 256, .al = [] { return dInt(g_orkestraTcpMaksGovdeMB); }, .ata = [](const AyarDeger& d) { g_orkestraTcpMaksGovdeMB = d.i; }}); s.ayarKaydet({.kimlik = "orkestra.eslesme_ttl_sn", .kategori = "Orkestra", .ad = "Eşleştirme istek süresi (sn)", .aciklama = "Bekleyen eşleştirme isteği bu süre içinde onaylanmazsa iptal " "olur (kullanıcı kodları karşılaştırma penceresi).", .tip = AyarTip::Int, .varsayilan = dInt(120), .min = 15, .maks = 600, .al = [] { return dInt((i64)g_orkestraEslesmeTtlSn); }, .ata = [](const AyarDeger& d) { g_orkestraEslesmeTtlSn = (u64)d.i; }}); s.ayarKaydet({.kimlik = "orkestra.task_puan_cpu", .kategori = "Orkestra", .ad = "Yerleştirme: CPU ağırlığı (%)", .aciklama = "Otomatik görev yerleştirmede boş CPU'ya verilen önem. Yüksek = " "işleri CPU'su boş node'lara yığ.", .tip = AyarTip::Int, .varsayilan = dInt(50), .min = 0, .maks = 100, .al = [] { return dInt(g_orkestraPuanCpu); }, .ata = [](const AyarDeger& d) { g_orkestraPuanCpu = d.i; }}); s.ayarKaydet({.kimlik = "orkestra.task_puan_task", .kategori = "Orkestra", .ad = "Yerleştirme: kuyruk ağırlığı (%)", .aciklama = "Az aktif görevli node'a verilen önem (yük dengesi).", .tip = AyarTip::Int, .varsayilan = dInt(40), .min = 0, .maks = 100, .al = [] { return dInt(g_orkestraPuanTask); }, .ata = [](const AyarDeger& d) { g_orkestraPuanTask = d.i; }}); s.ayarKaydet({.kimlik = "orkestra.task_puan_bellek", .kategori = "Orkestra", .ad = "Yerleştirme: bellek ağırlığı (%)", .aciklama = "RAM uygunluğuna verilen önem.", .tip = AyarTip::Int, .varsayilan = dInt(10), .min = 0, .maks = 100, .al = [] { return dInt(g_orkestraPuanBellek); }, .ata = [](const AyarDeger& d) { g_orkestraPuanBellek = d.i; }}); s.ayarKaydet({.kimlik = "orkestra.task_puan_doyum", .kategori = "Orkestra", .ad = "Yerleştirme: doyum görev sayısı", .aciklama = "Bir node'u 'tam dolu' sayan aktif görev sayısı (normalizasyon).", .tip = AyarTip::Int, .varsayilan = dInt(8), .min = 1, .maks = 128, .al = [] { return dInt(g_orkestraPuanDoyum); }, .ata = [](const AyarDeger& d) { g_orkestraPuanDoyum = d.i; }}); s.ayarKaydet({.kimlik = "orkestra.transfer_parca_kb", .kategori = "Orkestra", .ad = "Dosya transfer parça boyu (KB)", .aciklama = "Büyük dosyalar bu boyutta parçalara bölünüp gönderilir " "(MTU/tampon dengesi).", .tip = AyarTip::Int, .varsayilan = dInt(256), .min = 4, .maks = 4096, .al = [] { return dInt(g_orkestraTransferParcaKB); }, .ata = [](const AyarDeger& d) { g_orkestraTransferParcaKB = d.i; }}); // ── İş Takip (Kral + MongoDB — docs/istakip_tasarim.md) ─────────────────── s.ayarKaydet({.kimlik = "istakip.kral", .kategori = "İş Takip", .ad = "Bu makine Kral (sunucu)", .aciklama = "İş Takip verisinin sahibi bu fikocad olur: MongoDB'ye " "bağlanır ve İş Takip portunu dinler. Diğer makineler " "'Kral adresi' ile buraya bağlanır. KAPALI: hiçbir soket/" "veritabanı bağlantısı açılmaz (varsayılan).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(g_istakipKral); }, .ata = [](const AyarDeger& d) { g_istakipKral = d.b; }}); s.ayarKaydet({.kimlik = "istakip.port", .kategori = "İş Takip", .ad = "Kral portu", .aciklama = "Kralın dinlediği TCP portu; istemci adresinde port " "verilmezse de bu kullanılır.", .tip = AyarTip::Int, .varsayilan = dInt(47820), .min = 1024, .maks = 65535, .al = [] { return dInt(g_istakipPort); }, .ata = [](const AyarDeger& d) { g_istakipPort = d.i; }}); s.ayarKaydet({.kimlik = "istakip.kral_adres", .kategori = "İş Takip", .ad = "Kral adresi (istemci)", .aciklama = "Bağlanılacak kral: 'ip:port' veya sadece 'ip' (örn. " "192.168.1.10:47820). Boş = istemci kapalı. Uzaktan (WAN) " "doğrudan IP ile de bağlanılır.", .tip = AyarTip::Metin, .varsayilan = dMetin(""), .al = [] { return dMetin(g_istakipKralAdres.c_str()); }, .ata = [](const AyarDeger& d) { g_istakipKralAdres = d.metin; }}); s.ayarKaydet({.kimlik = "istakip.mongo_uri", .kategori = "İş Takip", .ad = "MongoDB adresi (kral)", .aciklama = "Kralın bağlandığı MongoDB (mongodb://host:port/veritabani). " "MongoDB kurulumunu siz sağlarsınız — FikoCAD yalnız bağlanır.", .tip = AyarTip::Metin, .varsayilan = dMetin("mongodb://localhost:27017/fiko_istakip"), .al = [] { return dMetin(g_istakipMongoUri.c_str()); }, .ata = [](const AyarDeger& d) { g_istakipMongoUri = d.metin; }}); s.ayarKaydet({.kimlik = "istakip.istemci_yazabilir", .kategori = "İş Takip", .ad = "İstemciler yazabilir", .aciklama = "Kapalıyken uzak istemciler salt-okur (yalnız kral makinesi " "kayıt açar/değiştirir).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_istakipIstemciYazabilir); }, .ata = [](const AyarDeger& d) { g_istakipIstemciYazabilir = d.b; }}); s.ayarKaydet({.kimlik = "istakip.kimlik_dogrulama", .kategori = "İş Takip", .ad = "Kimlik doğrulama (eşleştirme zorunlu)", .aciklama = "Açıkken kral yalnız Orchestrator'dan EŞLEŞTİRİLMİŞ makineleri " "kabul eder (TOFU anahtarıyla kanıt sınaması). Eşleşmemiş " "istemci veri alamaz/yazamaz. Kapalı: yerel ağ güven modeli " "(varsayılan).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(g_istakipKimlik); }, .ata = [](const AyarDeger& d) { g_istakipKimlik = d.b; }}); s.ayarKaydet({.kimlik = "istakip.snapshot_parca", .kategori = "İş Takip", .ad = "Snapshot dilim boyu (kayıt)", .aciklama = "Yeni bağlanan istemciye döküm bu boyda dilimlerle gider " "(dev tek çerçeve yerine — büyük veride ölçeklenir).", .tip = AyarTip::Int, .varsayilan = dInt(512), .min = 16, .maks = 65536, .al = [] { return dInt(g_istakipSnapshotParca); }, .ata = [](const AyarDeger& d) { g_istakipSnapshotParca = d.i; }}); struct Esik { const char* kimlik; const char* ad; const char* aciklama; const char* dedektor; const char* anahtar; f64* golge; f32 min; f32 maks; }; static const Esik esikler[] = { {"zeka.fillet.teget_aci_tol", "Fillet: teğet açı toleransı (°)", "İki komşu yüz arasındaki dihedral açı bu değerin altındaysa bağlantı teğet (G1) " "sayılır — fillet şerit adaylığının temel şartı.", "fillet", "teget_aci_tol", &g_zekaFilletTegetTol, 0.1f, 45.0f}, {"zeka.fillet.yaricap_uyum_tol", "Fillet: zincir yarıçap uyumu (mm)", "Zincirde komşu fillet üyeleri arasındaki azami R farkı — üstündeyse zincir kopar.", "fillet", "yaricap_uyum_tol", &g_zekaFilletYaricapTol, 0.001f, 5.0f}, {"zeka.cep.slot_oran", "Cep: slot uzun/geniş oranı", "Cep dış konturunun uzun/geniş oranı bu eşiği aşarsa cep Slot olarak sınıflanır.", "cep", "slot_oran", &g_zekaCepSlotOran, 1.0f, 20.0f}, {"zeka.cep.boss_alan_oran", "Cep: boss tepe alan oranı", "Boss tepe alanı / gövdenin en büyük yüz alanı bu oranın altında olmalı — dış kabuk " "yüzleri boss sanılmasın.", "cep", "boss_alan_oran", &g_zekaCepBossAlanOran, 0.01f, 1.0f}, {"zeka.pah.serit_oran", "Pah: şerit darlık oranı", "Yüz alanı / (en uzun kenar)² bu oranın altındaysa yüz pah şeridi kadar dardır.", "pah", "serit_oran", &g_zekaPahSeritOran, 0.01f, 1.0f}, }; for (const Esik& e : esikler) s.ayarKaydet({.kimlik = e.kimlik, .kategori = "Zekâ", .ad = e.ad, .aciklama = e.aciklama, .tip = AyarTip::F32, .varsayilan = dF(*e.golge), .min = e.min, .maks = e.maks, .al = [g = e.golge] { return dF(*g); }, .ata = [z, golge = e.golge, det = e.dedektor, ant = e.anahtar](const AyarDeger& d) { *golge = d.f; if (zeka::Dedektor* dd = z->dedektor(det)) dd->esikAyarla(ant, d.f); }}); } void kaydetEklenti(AyarSistemi& s) { s.ayarKaydet({.kimlik = "eklenti.dinamik_komut_ustte", .kategori = "Eklenti", .ad = "Dinamik komut penceresi üstte", .aciklama = "Lua/DLL eklentiden gelen pencereli komutlar açılınca " "pencere varsayılan olarak diğer pencerelerin önünde kalsın.", .tip = AyarTip::Bool, .varsayilan = dBool(dinamikKomutUstteVarsayilan()), .al = [] { return dBool(dinamikKomutUstteVarsayilan()); }, .ata = [](const AyarDeger& d) { dinamikKomutUstteVarsayilan() = d.b; }}); } void kaydetGeriBildirim(AyarSistemi& s) { s.ayarKaydet({.kimlik = "geribildirim.sunucu", .kategori = "Geri Bildirim", .ad = "Sunucu adresi", .aciklama = "Geri bildirimin gönderileceği FikoYT sunucusu (şema + host + port).", .tip = AyarTip::Metin, .varsayilan = dMetin(geriBildirimSunucu().c_str()), .al = [] { return dMetin(geriBildirimSunucu().c_str()); }, .ata = [](const AyarDeger& d) { geriBildirimSunucu() = d.metin; }}); s.ayarKaydet({.kimlik = "geribildirim.koleksiyon", .kategori = "Geri Bildirim", .ad = "MongoDB koleksiyonu", .aciklama = "Kayıtların yazılacağı koleksiyon. Yalnız harf/rakam/alt çizgi; " "'hareketler' olamaz (sunucu yetki reddi), '.' ve '-' route'u bozar.", .tip = AyarTip::Metin, .varsayilan = dMetin(geriBildirimKoleksiyon().c_str()), .al = [] { return dMetin(geriBildirimKoleksiyon().c_str()); }, .ata = [](const AyarDeger& d) { geriBildirimKoleksiyon() = d.metin; }}); s.ayarKaydet({.kimlik = "geribildirim.ekran_goruntusu", .kategori = "Geri Bildirim", .ad = "Ekran görüntüsünü otomatik ekle", .aciklama = "Geri bildirim penceresi açılınca 3B görünümün o anki karesi " "otomatik yakalanır (kutu ile kaldırılabilir).", .tip = AyarTip::Bool, .varsayilan = dBool(geriBildirimEkranGoruntusuVarsayilan()), .al = [] { return dBool(geriBildirimEkranGoruntusuVarsayilan()); }, .ata = [](const AyarDeger& d) { geriBildirimEkranGoruntusuVarsayilan() = d.b; }}); s.ayarKaydet({.kimlik = "geribildirim.zaman_asimi_sn", .kategori = "Geri Bildirim", .ad = "Zaman aşımı (sn)", .aciklama = "Sunucu yanıt vermezse gönderimin vazgeçeceği süre.", .tip = AyarTip::Int, .varsayilan = dInt(geriBildirimZamanAsimiSn()), .min = 5, .maks = 120, .al = [] { return dInt(geriBildirimZamanAsimiSn()); }, .ata = [](const AyarDeger& d) { geriBildirimZamanAsimiSn() = (int)d.i; }}); s.ayarKaydet({.kimlik = "geribildirim.maks_mb", .kategori = "Geri Bildirim", .ad = "Azami gönderi boyutu (MB)", .aciklama = "Ekran görüntüsü base64 olarak gövdeye gömülür. MongoDB doküman " "sınırı 16 MB — bu eşiği aşan gönderi reddedilir.", .tip = AyarTip::Int, .varsayilan = dInt(geriBildirimMaksMb()), .min = 1, .maks = 12, .al = [] { return dInt(geriBildirimMaksMb()); }, .ata = [](const AyarDeger& d) { geriBildirimMaksMb() = (int)d.i; }}); } void kaydetLisans(AyarSistemi& s) { (void)s; // Lisans kapısı dağıtımda zorunludur; ayarlardan devre dışı bırakılamaz. } void kaydetArac(AyarSistemi& s) { s.ayarKaydet({.kimlik = "arac.lisanstan_otomatik", .kategori = "Lisans", .ad = "Tek araçlı lisansta araç kipinde aç", .aciklama = "Açık (varsayılan): lisans YALNIZ tek bir aracı kapsıyorsa " "(ör. sadece \"FikoYT Diagonal Kafa\") program tam CAD yerine " "doğrudan o aracı ana pencere olarak açar. Kapalı: her zaman " "tam CAD açılır; araç kipi yalnız --arac= komut satırı " "bayrağı veya FIKO_ARAC ortam değişkeni ile açılır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(aracLisanstanOtomatik()); }, .ata = [](const AyarDeger& d) { aracLisanstanOtomatikAyarla(d.b); }}); s.ayarKaydet({.kimlik = "arac.pencere_genislik", .kategori = "Lisans", .ad = "Araç penceresi genişliği (px)", .aciklama = "Araç kipinde açılış pencere genişliği (istemci alanı). Pencereyi elle " "boyutlandırınca bu ayar KENDİLİĞİNDEN güncellenir — bir " "dahaki açılış aynı ölçüde gelir.", .tip = AyarTip::Int, .varsayilan = dInt(282), .min = 200, .maks = 2560, .al = [] { return dInt(aracPencereGenislik()); }, .ata = [](const AyarDeger& d) { aracPencereGenislikAyarla((int)d.i); }}); s.ayarKaydet({.kimlik = "arac.pencere_yukseklik", .kategori = "Lisans", .ad = "Araç penceresi yüksekliği (px)", .aciklama = "Araç kipinde açılış pencere yüksekliği.", .tip = AyarTip::Int, .varsayilan = dInt(416), .min = 200, .maks = 1600, .al = [] { return dInt(aracPencereYukseklik()); }, .ata = [](const AyarDeger& d) { aracPencereYukseklikAyarla((int)d.i); }}); s.ayarKaydet({.kimlik = "arac.gosterici_oran", .kategori = "Lisans", .ad = "3B gösterici oranı", .aciklama = "Araç kipinde 3B gösterici yüksekliği = pencere genişliği × bu " "oran. Sabit piksel yerine orantılı: pencere daraldıkça " "gösterici de küçülür, en-boy oranı korunur.", .tip = AyarTip::F32, .varsayilan = dF(0.75), .min = 0.3, .maks = 2.0, .al = [] { return dF(aracGostericiOran()); }, .ata = [](const AyarDeger& d) { aracGostericiOranAyarla((f32)d.f); }}); } void kaydetGuncelleme(AyarSistemi& s) { GuncellemeServisi* gs = &guncellemeServisi(); static const char* modAd[3] = {"Otomatik", "Sor", "Bildir"}; s.ayarKaydet({.kimlik = "guncelleme.mod", .kategori = "Güncelleme", .ad = "Kurulum modu", .aciklama = "Otomatik = sessizce indir + uygun anda kur + bildir. " "Sor = yeni sürümde onay iste. Bildir = yalnız haber ver.", .tip = AyarTip::Secenek, .varsayilan = dMetin(modAd[0]), .secenekler = {modAd[0], modAd[1], modAd[2]}, .al = [gs] { return dMetin(modAd[(int)gs->mod()]); }, .ata = [gs](const AyarDeger& d) { for (int i = 0; i < 3; ++i) if (d.metin == modAd[i]) gs->modAyarla((GuncellemeServisi::Mod)i); }}); s.ayarKaydet({.kimlik = "guncelleme.oto_kontrol", .kategori = "Güncelleme", .ad = "Açılışta otomatik denetle", .aciklama = "Uygulama açılınca arka planda yeni sürüm denetle.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [gs] { return dBool(gs->otoKontrol()); }, .ata = [gs](const AyarDeger& d) { gs->otoKontrolAyarla(d.b); }}); static const char* kanalAd[3] = {"kararli", "beta", "gece"}; s.ayarKaydet({.kimlik = "guncelleme.kanal", .kategori = "Güncelleme", .ad = "Sürüm kanalı", .aciklama = "kararli = önerilen. beta/gece = erken erişim (daha sık, riskli).", .tip = AyarTip::Secenek, .varsayilan = dMetin(kanalAd[0]), .secenekler = {kanalAd[0], kanalAd[1], kanalAd[2]}, .al = [gs] { return dMetin(gs->kanal().c_str()); }, .ata = [gs](const AyarDeger& d) { gs->kanalAyarla(d.metin); }}); s.ayarKaydet({.kimlik = "guncelleme.sunucu_host", .kategori = "Güncelleme", .ad = "Güncelleme sunucusu", .aciklama = "Manifest'in çekileceği sunucu adı (kendi Go backend).", .tip = AyarTip::Metin, .varsayilan = dMetin(gs->sunucu().host.c_str()), .al = [gs] { return dMetin(gs->sunucu().host.c_str()); }, .ata = [gs](const AyarDeger& d) { gs->sunucu().host = d.metin; }}); s.ayarKaydet({.kimlik = "guncelleme.sunucu_port", .kategori = "Güncelleme", .ad = "Sunucu portu", .aciklama = "Güncelleme sunucusu portu (Go backend: 9000).", .tip = AyarTip::Int, .varsayilan = dInt(gs->sunucu().port), .min = 1, .maks = 65535, .al = [gs] { return dInt(gs->sunucu().port); }, .ata = [gs](const AyarDeger& d) { gs->sunucu().port = (u16)d.i; }}); } // ---- Geçici dosyalar (tek ağaç: /gecici) ------------------------------ // Politika değerleri burada yaşar; gecici.hpp saf yol/dosya katmanıdır (ayar bilmez). int& geciciMaksGun() { static int v = 30; return v; } i64& geciciMaksMb() { static i64 v = 4096; return v; } bool& geciciAcilistaBuda() { static bool v = true; return v; } void geciciBakimYap() { gecici::buda({.maksGun = geciciMaksGun(), .maksMb = (u64)std::max(0, geciciMaksMb())}); } void kaydetGecici(AyarSistemi& s) { s.ayarKaydet({.kimlik = "gecici.dizin", .kategori = "Geçici Dosyalar", .ad = "Geçici dizin", .aciklama = "Tüm önbellek/geçici dosyaların kökü. BOŞ = uygulama dizini " "altında 'gecici'. Hiçbir türev dosya artık kaynak dosyanın " "yanına yazılmaz. Değişiklik anında geçerli; eski içerik taşınmaz.", .tip = AyarTip::Metin, .varsayilan = dMetin(""), .al = [] { return dMetin(gecici::kokAyar()); }, .ata = [](const AyarDeger& d) { gecici::kokAta(d.metin); }}); s.ayarKaydet({.kimlik = "gecici.maks_gun", .kategori = "Geçici Dosyalar", .ad = "Saklama süresi (gün)", .aciklama = "Bu yaştan eski geçici dosyalar budamada silinir. 0 = yaş sınırı yok.", .tip = AyarTip::Int, .varsayilan = dInt(30), .min = 0, .maks = 365, .al = [] { return dInt(geciciMaksGun()); }, .ata = [](const AyarDeger& d) { geciciMaksGun() = (int)d.i; }}); s.ayarKaydet({.kimlik = "gecici.maks_mb", .kategori = "Geçici Dosyalar", .ad = "Boyut tavanı (MB)", .aciklama = "Geçici ağaç bu boyutu aşarsa en eski dosyalardan başlanarak " "silinir. 0 = sınırsız. STEP önbelleği burada yaşar — çok küçük " "değer ikinci açılış hızını kaybettirir.", .tip = AyarTip::Int, .varsayilan = dInt(4096), .min = 0, .maks = 262144, .al = [] { return dInt(geciciMaksMb()); }, .ata = [](const AyarDeger& d) { geciciMaksMb() = d.i; }}); s.ayarKaydet({.kimlik = "gecici.acilista_buda", .kategori = "Geçici Dosyalar", .ad = "Açılışta buda", .aciklama = "Uygulama açılırken yaş/boyut politikasını arka planda uygular. " "Kapalı = temizlik yalnız elle (Araçlar ▸ Geçici dosyaları temizle).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(geciciAcilistaBuda()); }, .ata = [](const AyarDeger& d) { geciciAcilistaBuda() = d.b; }}); } // Pencere görünümü: "WebCam" tarzını kullanan TÜM panellerin (CAM Simülasyon, Açılı // Kafa, Analiz, Malzeme, Lisans Üretici…) ortak arka plan ızgarası. Motor saf kalır — // değerler ui::webSkinGrid* setter'larıyla enjekte edilir. void kaydetPencere(AyarSistemi& s) { s.ayarKaydet({.kimlik = "pencere.grid_adim", .kategori = "Pencere", .ad = "Izgara adımı (px)", .aciklama = "Bu tarzı kullanan tüm panellerin teal cam zemininde çizilen " "arka plan ızgarasının hücre boyu (piksel). Küçük = daha sık / " "minik kareler. Saf görsel; hiçbir davranışı etkilemez.", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = 2.0, .maks = 40.0, .al = [] { return dF(ui::webSkinGridAdim()); }, .ata = [](const AyarDeger& d) { ui::webSkinGridAdimAyarla((f32)d.f); kareIste(2); }}); s.ayarKaydet({.kimlik = "pencere.grid_goster", .kategori = "Pencere", .ad = "Izgara göster", .aciklama = "Kapalı: arka plan ızgarası hiç çizilmez (düz cam zemin).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(ui::webSkinGridGoster()); }, .ata = [](const AyarDeger& d) { ui::webSkinGridGosterAyarla(d.b); kareIste(2); }}); // Grid renk ayarı - RGB (0-1 aralığı). Varsayılan: cyan (150/255, 1.0, 1.0) s.ayarKaydet({.kimlik = "pencere.grid_renk", .kategori = "Pencere", .ad = "Izgara rengi", .aciklama = "Grid çizgi renginin RGB değerleri (0-1). Varsayılan: cyan.", .tip = AyarTip::Renk, .varsayilan = dRenk({150.0f/255.0f, 1.0f, 1.0f}), .al = [] { return dRenk({ui::webSkinGridR()/255.0f, ui::webSkinGridG()/255.0f, ui::webSkinGridB()/255.0f}); }, .ata = [](const AyarDeger& d) { const u8 r = (u8)(d.renk.x * 255.0f); const u8 g = (u8)(d.renk.y * 255.0f); const u8 b = (u8)(d.renk.z * 255.0f); ui::webSkinGridRenkAyarla(r, g, b); kareIste(2); }}); s.ayarKaydet({.kimlik = "pencere.skin_webcam", .kategori = "Pencere", .ad = "Cam/ızgara pencere görünümü", .aciklama = "Tüm paneller açılı-kafa pencereleri tarzında: teal cam zemin, " "cyan kenar, arka plan ızgarası, pill slider. Kapalı: eski " "düz tema.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(ui::pencereVarsayilanSkin() == ui::PencereSkin::WebCam); }, .ata = [](const AyarDeger& d) { ui::pencereVarsayilanSkinAyarla(d.b ? ui::PencereSkin::WebCam : ui::PencereSkin::Varsayilan); kareIste(2); }}); s.ayarKaydet({.kimlik = "pencere.konum_hatirla", .kategori = "Pencere", .ad = "Pencere konumlarını hatırla", .aciklama = "Panel/pencere konum ve boyutları oturumlar arası saklanır " "(fikocad.pencere.ini). Kapalı: eski davranış — her açılışta " "varsayılan yerleşim. Değişiklik yeniden başlatmada etkir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(pencereKonumHatirla()); }, .ata = [](const AyarDeger& d) { pencereKonumHatirla() = d.b; }}); s.ayarKaydet({.kimlik = "pencere.disari_tasima", .kategori = "Pencere", .ad = "Panelleri ana pencere dışına taşımaya izin ver (Multi-Viewport)", .aciklama = "Paneller/pencereler sürüklendiğinde ana fikocad penceresinin dışına " "çıkarılabilir (bağımsız OS penceresi olarak açılır). Kapalı: paneller " "yalnız ana pencere sınırları içinde sürüklenebilir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(pencereDisariTasima()); }, .ata = [](const AyarDeger& d) { pencereDisariTasima() = d.b; kareIste(3); }}); } void kaydetOtoKayit(AyarSistemi& s) { s.ayarKaydet({.kimlik = "otokayit.aktif", .kategori = "Geçici Dosyalar", .ad = "Otomatik kayıt", .aciklama = "Model değiştikten sonra belirli aralıklarla anlık görüntü alır " "(geçici dizine; kendi dosyanıza DOKUNMAZ). Çökme/kesintide " "açılışta kurtarma teklif edilir. Temiz kapanışta iz kalmaz.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(otoKayitAktif()); }, .ata = [](const AyarDeger& d) { otoKayitAktif() = d.b; }}); s.ayarKaydet({.kimlik = "otokayit.dakika", .kategori = "Geçici Dosyalar", .ad = "Otomatik kayıt aralığı (dakika)", .aciklama = "Yalnız model DEĞİŞTİYSE sayar; seçim/gezinme tetiklemez. " "Dev modelde çok kısa aralık disk yazımını artırır.", .tip = AyarTip::F64, .varsayilan = dF(5.0), .min = 0.5, .maks = 60, .al = [] { return dF(otoKayitDakika()); }, .ata = [](const AyarDeger& d) { otoKayitDakika() = d.f; }}); s.ayarKaydet({.kimlik = "otokayit.kusak", .kategori = "Geçici Dosyalar", .ad = "Saklanan kuşak sayısı", .aciklama = "Dönüşümlü yazılan anlık görüntü adedi. 3 = son üç kayıt durur " "(sonuncusu bozuksa bir öncekine dönülebilir).", .tip = AyarTip::Int, .varsayilan = dInt(3), .min = 1, .maks = 10, .al = [] { return dInt(otoKayitKusakSayisi()); }, .ata = [](const AyarDeger& d) { otoKayitKusakSayisi() = (int)d.i; }}); } void kaydetPafta(AyarSistemi& s) { s.ayarKaydet({.kimlik = "pafta.kenar_payi_px", .kategori = "Teknik Resim", .ad = "Sayfa kenar payı (px)", .aciklama = "Teknik resim modunda sayfanın viewport kenarına bırakılan boşluk. " "Büyütmek sayfayı küçültür (zoom ile bağımsızca yakınlaşılır).", .tip = AyarTip::F64, .varsayilan = dF(16.0), .min = 0, .maks = 200, .al = [] { return dF(paftaKenarPayiPx()); }, .ata = [](const AyarDeger& d) { paftaKenarPayiPx() = d.f; }}); s.ayarKaydet({.kimlik = "pafta.vur_tolerans_mm", .kategori = "Teknik Resim", .ad = "Görünüm yakalama toleransı (mm)", .aciklama = "Görünümün sınır kutusuna eklenen tutma payı — kenarından kavrayıp " "sürüklemeyi kolaylaştırır. 0 = tam sınır kutusu.", .tip = AyarTip::F64, .varsayilan = dF(2.0), .min = 0, .maks = 20, .al = [] { return dF(paftaVurToleransMm()); }, .ata = [](const AyarDeger& d) { paftaVurToleransMm() = d.f; }}); s.ayarKaydet({.kimlik = "pafta.cizgi_kalinlik", .kategori = "Teknik Resim", .ad = "Görünür çizgi kalınlığı (px)", .aciklama = "Sürekli (görünür) kenar kalınlığı; gizli çizgi bunun %90'ı ve kesikli.", .tip = AyarTip::F32, .varsayilan = dF(1.4), .min = 0.5, .maks = 5, .al = [] { return dF(paftaCizgiKalinlik()); }, .ata = [](const AyarDeger& d) { paftaCizgiKalinlik() = (f32)d.f; }}); s.ayarKaydet({.kimlik = "pafta.tutunma_px", .kategori = "Teknik Resim", .ad = "Ölçü tutunma yarıçapı (px)", .aciklama = "Ölçü yerleştirirken köşe/çember merkezi yakalama mesafesi. " "Adaylar B-Rep'ten gelir (görsel HLR çizgilerinden DEĞİL).", .tip = AyarTip::F64, .varsayilan = dF(10.0), .min = 0, .maks = 60, .al = [] { return dF(paftaTutunmaPx()); }, .ata = [](const AyarDeger& d) { paftaTutunmaPx() = d.f; }}); s.ayarKaydet({.kimlik = "pafta.ok_boyu_mm", .kategori = "Teknik Resim", .ad = "Ölçü ok başı boyu (mm)", .aciklama = "Ölçü çizgisi uçlarındaki ok üçgeninin sayfa üzerindeki uzunluğu.", .tip = AyarTip::F64, .varsayilan = dF(3.0), .min = 0.5, .maks = 15, .al = [] { return dF(paftaOkBoyuMm()); }, .ata = [](const AyarDeger& d) { paftaOkBoyuMm() = d.f; }}); s.ayarKaydet({.kimlik = "pafta.tarama_aci", .kategori = "Teknik Resim", .ad = "Kesit tarama açısı (°)", .aciklama = "Kesit yüzeyi tarama (hatch) çizgilerinin eğimi. ISO geleneği 45°.", .tip = AyarTip::F64, .varsayilan = dF(45.0), .min = 0, .maks = 180, .al = [] { return dF(paftaTaramaAci()); }, .ata = [](const AyarDeger& d) { paftaTaramaAci() = d.f; }}); s.ayarKaydet({.kimlik = "pafta.tarama_aralik_mm", .kategori = "Teknik Resim", .ad = "Kesit tarama aralığı (mm)", .aciklama = "Tarama çizgileri arası mesafe (sayfa mm). Küçük değer koyu " "tarama + daha çok çizgi demektir.", .tip = AyarTip::F64, .varsayilan = dF(3.0), .min = 0.3, .maks = 30, .al = [] { return dF(paftaTaramaAralikMm()); }, .ata = [](const AyarDeger& d) { paftaTaramaAralikMm() = d.f; }}); s.ayarKaydet({.kimlik = "pafta.zoom_adim", .kategori = "Teknik Resim", .ad = "Tekerlek zoom çarpanı", .aciklama = "Fare tekerleği başına yakınlaştırma oranı (1.12 = %12).", .tip = AyarTip::F32, .varsayilan = dF(1.12), .min = 1.01, .maks = 2, .al = [] { return dF(paftaZoomAdim()); }, .ata = [](const AyarDeger& d) { paftaZoomAdim() = (f32)d.f; }}); s.ayarKaydet({.kimlik = "pafta.yazi_mm", .kategori = "Pafta", .ad = "Ölçü metni boyu (sayfa mm)", .aciklama = "Ölçü metinlerinin SAYFA milimetresi cinsinden boyu (ISO ~3.5). " "Sayfa-ölçekli kip açıkken geçerli.", .tip = AyarTip::F32, .varsayilan = dF(3.5), .min = 1.0, .maks = 10.0, .al = [] { return dF(paftaYaziMm()); }, .ata = [](const AyarDeger& d) { paftaYaziMm() = (f32)d.f; }}); s.ayarKaydet({.kimlik = "pafta.yazi_sayfa_olcekli", .kategori = "Pafta", .ad = "Ölçü metni sayfayla ölçeklensin", .aciklama = "Teknik resim davranışı: metin sayfa mm'siyle büyür/küçülür " "(zoom'da orantı korunur — kâğıt önizleme). Kapalı: eski " "px-sabit metin (zoom'dan bağımsız ekran boyu).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(paftaYaziSayfaOlcekli()); }, .ata = [](const AyarDeger& d) { paftaYaziSayfaOlcekli() = d.b; }}); s.ayarKaydet({.kimlik = "pafta.pmi_goster", .kategori = "Pafta", .ad = "3B PMI paftaya yansıt", .aciklama = "3B PMI/GD&T öğeleri (FCF, datum, not) ilgili görünümlerde lider " "+ kutu olarak çizilir (türetilmiş — PMI değişince pafta güncel). " "Kapalı: eski davranış (PMI çizilmez).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(paftaPmiGoster()); }, .ata = [](const AyarDeger& d) { paftaPmiGoster() = d.b; }}); } void kaydetPmi(AyarSistemi& s) { s.ayarKaydet({.kimlik = "pmi.cerceve_dolgu_px", .kategori = "PMI", .ad = "Çerçeve iç dolgu (px)", .aciklama = "GD&T/not çerçevesinin metin etrafındaki iç boşluğu.", .tip = AyarTip::F32, .varsayilan = dF(6.0), .min = 0, .maks = 30, .al = [] { return dF(pmiCerceveDolguPx()); }, .ata = [](const AyarDeger& d) { pmiCerceveDolguPx() = (f32)d.f; }}); s.ayarKaydet({.kimlik = "pmi.ok_boyu_px", .kategori = "PMI", .ad = "Lider ok başı (px)", .aciklama = "PMI lider çizgisinin hedefe saplanan ok ucu uzunluğu.", .tip = AyarTip::F32, .varsayilan = dF(10.0), .min = 2, .maks = 40, .al = [] { return dF(pmiOkBoyuPx()); }, .ata = [](const AyarDeger& d) { pmiOkBoyuPx() = (f32)d.f; }}); s.ayarKaydet({.kimlik = "pmi.lod_esigi_px", .kategori = "PMI", .ad = "Uzaklık LOD eşiği (px)", .aciklama = "Çerçeve ekranda bundan küçükse yalnız nokta işareti çizilir " "(uzak PMI kalabalığı kare bütçesini yemez).", .tip = AyarTip::F32, .varsayilan = dF(14.0), .min = 0, .maks = 100, .al = [] { return dF(pmiLodEsigiPx()); }, .ata = [](const AyarDeger& d) { pmiLodEsigiPx() = (f32)d.f; }}); } void kaydetPmiOrtme(AyarSistemi& s) { s.ayarKaydet({.kimlik = "pmi.ortme_kontrolu", .kategori = "PMI", .ad = "Parça arkasında soluklaştır", .aciklama = "PMI çerçevesinin çapası parçanın arkasında kalıyorsa çerçeve " "soluk çizilir (BVH ışını, önbellekli — kamera durunca maliyet " "sıfır). Kapalı = her zaman tam görünür (varsayılan).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(pmiOrtmeKontrolu()); }, .ata = [](const AyarDeger& d) { pmiOrtmeKontrolu() = d.b; }}); } void kaydetPerformans(AyarSistemi& s) { s.ayarKaydet({.kimlik = "performans.talep_uzerine_render", .kategori = "Performans", .ad = "Talep-üzerine render (pil dostu)", .aciklama = "Boştayken GPU'yu monitör hızında (200+ FPS) koşturmaz; " "yalnız girdi/animasyon değişiminde çizer. Kapalı = her zaman çiz.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(kareIstekAcik()); }, .ata = [](const AyarDeger& d) { kareIstekAc(d.b); kareIste(4); }}); s.ayarKaydet({.kimlik = "performans.fps_tavan", .kategori = "Performans", .ad = "Kare hızı tavanı (FPS)", .aciklama = "Aktif renderde üst FPS sınırı — GPU'yu binlerce FPS'te " "koşturmayı önler (ısı/güç/gürültü). 0 = sınırsız.", .tip = AyarTip::Int, .varsayilan = dInt(60), .min = 0, .maks = 240, .al = [] { return dInt(hedefFps()); }, .ata = [](const AyarDeger& d) { hedefFpsAta((int)d.i); kareIste(4); }}); } void kaydetAydinlatma(AyarSistemi& s, UygulamaBaglam& b) { IsikDurum* isik = &b.isik; const IsikDurum vars; // varsayılanlar = struct init değerleri (geriye-uyum) s.ayarKaydet({.kimlik = "aydinlatma.ortam_siddet", .kategori = "Aydınlatma", .ad = "Ortam (ambient) şiddeti", .aciklama = "Yönsüz taban aydınlatma düzeyi.", .tip = AyarTip::F32, .varsayilan = dF(vars.ortamSiddet), .min = 0, .maks = 1, .al = [isik] { return dF(isik->ortamSiddet); }, .ata = [isik](const AyarDeger& d) { isik->ortamSiddet = (f32)d.f; }}); s.ayarKaydet({.kimlik = "aydinlatma.ortam_renk", .kategori = "Aydınlatma", .ad = "Ortam rengi", .aciklama = "Ambient ışık rengi (RGB).", .tip = AyarTip::Renk, .varsayilan = dRenk(vars.ortamRenk), .al = [isik] { return dRenk(isik->ortamRenk); }, .ata = [isik](const AyarDeger& d) { isik->ortamRenk = d.renk; }}); isikAyarlari(s, "aydinlatma.isik1", &isik->isik1, vars.isik1, "Ana ışık (key)"); isikAyarlari(s, "aydinlatma.isik2", &isik->isik2, vars.isik2, "Dolgu ışık (fill)"); } void kaydetIzgara(AyarSistemi& s, UygulamaBaglam& b) { SketchUIDurum* sk = &b.sketch; s.ayarKaydet({.kimlik = "izgara.gorunur", .kategori = "Izgara & Snap", .ad = "Izgara görünür", .aciklama = "Sketch ızgarasını göster/gizle.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [sk] { return dBool(sk->sketchGrid); }, .ata = [sk](const AyarDeger& d) { sk->sketchGrid = d.b; }}); s.ayarKaydet({.kimlik = "izgara.adaptif", .kategori = "Izgara & Snap", .ad = "Adaptif ızgara (ekranı kapla)", .aciklama = "Izgara zoom'a göre 1/2/5 adımına uyarlanır ve DAİMA görünür " "ekranı kaplar (CAD sonsuz-grid). Kapalı: sabit aralık kullanılır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [sk] { return dBool(sk->sketchGridAdaptif); }, .ata = [sk](const AyarDeger& d) { sk->sketchGridAdaptif = d.b; }}); s.ayarKaydet({.kimlik = "izgara.snap", .kategori = "Izgara & Snap", .ad = "Izgaraya snap", .aciklama = "Çizim noktaları ızgara adımına yapışır.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [sk] { return dBool(sk->sketchGridSnap); }, .ata = [sk](const AyarDeger& d) { sk->sketchGridSnap = d.b; }}); s.ayarKaydet({.kimlik = "izgara.aralik", .kategori = "Izgara & Snap", .ad = "Izgara aralığı", .aciklama = "Izgara adımı (sketch birimi).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.1, .maks = 100, .al = [sk] { return dF(sk->sketchGridAralik); }, .ata = [sk](const AyarDeger& d) { sk->sketchGridAralik = (f32)d.f; }}); s.ayarKaydet({.kimlik = "izgara.aci_snap", .kategori = "Izgara & Snap", .ad = "Açı snap (derece)", .aciklama = "0 = kapalı; örn. 15 → çizgiler 15° katlarına yapışır.", .tip = AyarTip::F64, .varsayilan = dF(0), .min = 0, .maks = 90, .al = [sk] { return dF(sk->snapMotoru.aciSnapDeg); }, .ata = [sk](const AyarDeger& d) { sk->snapMotoru.aciSnapDeg = d.f; }}); s.ayarKaydet({.kimlik = "izgara.hizalama", .kategori = "Izgara & Snap", .ad = "Hizalama önerisi (inference)", .aciklama = "SmartPick yatay/dikey hizalama çizgileri.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [sk] { return dBool(sk->snapMotoru.inference); }, .ata = [sk](const AyarDeger& d) { sk->snapMotoru.inference = d.b; }}); } void kaydetKamera(AyarSistemi& s, UygulamaBaglam& b) { OrbitKamera* kam = &b.kamera; s.ayarKaydet({.kimlik = "kamera.ortografik", .kategori = "Kamera", .ad = "Ortografik izdüşüm", .aciklama = "Kapalı = perspektif, açık = ortografik (paralel).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [kam] { return dBool(kam->ortografik()); }, .ata = [kam](const AyarDeger& d) { kam->ortografikAyarla(d.b); }}); s.ayarKaydet({.kimlik = "kamera.fov", .kategori = "Kamera", .ad = "Görüş açısı (°)", .aciklama = "Perspektif dikey FOV. Küçük = tele, büyük = geniş açı.", .tip = AyarTip::F32, .varsayilan = dF(45.0), .min = 20, .maks = 100, .al = [kam] { return dF(kam->gorusAcisiDeg()); }, .ata = [kam](const AyarDeger& d) { kam->gorusAcisiDegAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "kamera.orbitHassasiyet", .kategori = "Kamera", .ad = "Döndürme hassasiyeti", .aciklama = "Orbit sürükleme hız çarpanı (1 = varsayılan).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.1, .maks = 5, .al = [kam] { return dF(kam->orbitHassasiyet()); }, .ata = [kam](const AyarDeger& d) { kam->orbitHassasiyetAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "kamera.panHassasiyet", .kategori = "Kamera", .ad = "Kaydırma hassasiyeti", .aciklama = "Pan sürükleme hız çarpanı (1 = varsayılan).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.1, .maks = 5, .al = [kam] { return dF(kam->panHassasiyet()); }, .ata = [kam](const AyarDeger& d) { kam->panHassasiyetAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "kamera.zoomOran", .kategori = "Kamera", .ad = "Yakınlaştırma oranı", .aciklama = "Tekerlek adımı başına mesafe oranı. Düşük = hızlı zoom.", .tip = AyarTip::F32, .varsayilan = dF(0.82), .min = 0.5, .maks = 0.98, .al = [kam] { return dF(kam->zoomOran()); }, .ata = [kam](const AyarDeger& d) { kam->zoomOranAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "kamera.yumusatma", .kategori = "Kamera", .ad = "Hareket yumuşatma", .aciklama = "Kamera geçiş yumuşaklığı. Düşük = ağır süzülme, yüksek = anında.", .tip = AyarTip::F32, .varsayilan = dF(14.0), .min = 1, .maks = 40, .al = [kam] { return dF(kam->yumusatma()); }, .ata = [kam](const AyarDeger& d) { kam->yumusatmaAta((f32)d.f); }}); } // ---- Dokunmatik / kalem ---------------------------------------------------- // Eşleme: her jest yuvası KENDİ Seçenek ayarıdır (custom = doğrudan bunları değiştir); // "Şema" ayarı hepsini birden bir önayara kurar. Şema OKUNURKEN semaCoz() ile canlı // tablodan türetilir → kullanıcı tek jesti değiştirince şema kendiliğinden "Özel"e // düşer (iki doğruluk kaynağı yok). const char* kDokunmaEylemAd[(size_t)girdi::DokunmaEylem::Sayi] = { "Yok", "Döndür", "Kaydır (pan)", "Yakınlaştır (zoom)", "İşaretçi (seçim/çizim)"}; const char* kDokunmaSemaAd[(size_t)girdi::DokunmaSema::Sayi] = { "FikoYT (1 parmak döndür)", "CATIA (1 parmak kaydır)", "Fare gibi (1 parmak seçim)", "Özel"}; // Bir jest yuvasını Seçenek ayarı olarak kaydeder (eylem adları tek tablodan). void dokunmaJestAyar(AyarSistemi& s, const char* kimlik, const char* ad, const char* aciklama, girdi::DokunmaJest jest, girdi::DokunmaEylem vars) { std::vector secenekler; for (const char* e : kDokunmaEylemAd) secenekler.push_back(e); s.ayarKaydet( {.kimlik = kimlik, .kategori = "Dokunmatik", .ad = ad, .aciklama = aciklama, .tip = AyarTip::Secenek, .varsayilan = dMetin(kDokunmaEylemAd[(size_t)vars]), .secenekler = std::move(secenekler), .al = [jest] { return dMetin(kDokunmaEylemAd[(size_t)dokunmaEslemeGlobal().al(jest)]); }, .ata = [jest](const AyarDeger& d) { for (size_t i = 0; i < (size_t)girdi::DokunmaEylem::Sayi; ++i) if (d.metin == kDokunmaEylemAd[i]) dokunmaEslemeGlobal().ata(jest, (girdi::DokunmaEylem)i); }}); } void kaydetDokunmatik(AyarSistemi& s) { s.ayarKaydet({.kimlik = "girdi.dokunmatik_aktif", .kategori = "Dokunmatik", .ad = "Dokunmatik ve kalem desteği", .aciklama = "Kapalıyken parmak/kalem girdisi Windows tarafından fare " "mesajına çevrilir (destek eklenmeden önceki davranış). " "Dokunmatik olmayan makinede bu ayarın etkisi yoktur.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(dokunmatikAktif()); }, .ata = [](const AyarDeger& d) { dokunmatikAktif() = d.b; }}); std::vector semalar; for (const char* a : kDokunmaSemaAd) semalar.push_back(a); s.ayarKaydet( {.kimlik = "girdi.dokunma_sema", .kategori = "Dokunmatik", .ad = "Jest şeması", .aciklama = "Hazır eşleme: FikoYT (CAD standardı; 1 parmak döndür, 2 parmak " "kaydır+pinch), CATIA (1 parmak kaydır, 2 parmak döndür), Fare gibi " "(1 parmak seçim/kutu, 2 parmak döndür). Aşağıdaki jestlerden birini " "değiştirirsen şema kendiliğinden Özel olur.", .tip = AyarTip::Secenek, .varsayilan = dMetin(kDokunmaSemaAd[(size_t)girdi::DokunmaSema::FikoYT]), .secenekler = std::move(semalar), .al = [] { return dMetin(kDokunmaSemaAd[(size_t)dokunmaEslemeGlobal().semaCoz()]); }, .ata = [](const AyarDeger& d) { for (size_t i = 0; i < (size_t)girdi::DokunmaSema::Ozel; ++i) if (d.metin == kDokunmaSemaAd[i]) dokunmaEslemeGlobal() = girdi::DokunmaEsleme::semaEsleme((girdi::DokunmaSema)i); // "Özel" seçilmesi tabloyu DEĞİŞTİRMEZ: özel = jestleri elle kurmak demek. }}); dokunmaJestAyar(s, "girdi.dokunma_tek_parmak", "Tek parmak sürükle", "Bir parmakla sürüklendiğinde ne olsun.", girdi::DokunmaJest::TekParmakSurukle, girdi::DokunmaEylem::Dondur); dokunmaJestAyar(s, "girdi.dokunma_iki_parmak", "İki parmak sürükle", "İki parmağın ortak (orta nokta) kayması. Pinch ile AYNI ANDA çalışır.", girdi::DokunmaJest::IkiParmakSurukle, girdi::DokunmaEylem::Pan); dokunmaJestAyar(s, "girdi.dokunma_pinch", "İki parmak sıkıştır/aç (pinch)", "Parmak arası mesafenin değişimi.", girdi::DokunmaJest::IkiParmakPinch, girdi::DokunmaEylem::Zoom); dokunmaJestAyar(s, "girdi.dokunma_uc_parmak", "Üç parmak sürükle", "Üç parmağın ortak kayması.", girdi::DokunmaJest::UcParmakSurukle, girdi::DokunmaEylem::Yok); dokunmaJestAyar(s, "girdi.dokunma_kalem_uc", "Kalem ucu sürükle", "Kalem ucu (gövde tuşu basılı değil). İşaretçi = fare sol tuşuyla " "birebir aynı yol: seçim, seçim kutusu, sketch çizimi, hover.", girdi::DokunmaJest::KalemUcSurukle, girdi::DokunmaEylem::Isaretci); dokunmaJestAyar(s, "girdi.dokunma_kalem_govde", "Kalem gövde tuşu + sürükle", "Kalemin yan (barrel) tuşu basılıyken sürükleme.", girdi::DokunmaJest::KalemGovdeSurukle, girdi::DokunmaEylem::Dondur); girdi::DokunmaAyar* a = &dokunmaAyarGlobal(); s.ayarKaydet({.kimlik = "girdi.dokunma_surukleme_esik", .kategori = "Dokunmatik", .ad = "Sürükleme eşiği (px)", .aciklama = "Dokunuş bu kadar kayınca sürükleme sayılır. Altında kalırsa " "dokunuş/uzun bas olur. Parmak fareden kabadır → büyük tut.", .tip = AyarTip::F32, .varsayilan = dF(8.0), .min = 2, .maks = 30, .al = [a] { return dF(a->suruklemeEsik); }, .ata = [a](const AyarDeger& d) { a->suruklemeEsik = (f32)d.f; }}); s.ayarKaydet({.kimlik = "girdi.dokunma_uzun_bas", .kategori = "Dokunmatik", .ad = "Uzun bas süresi (s)", .aciklama = "Parmak hareketsiz bu kadar beklerse bağlam menüsü jesti.", .tip = AyarTip::F32, .varsayilan = dF(0.5), .min = 0.2, .maks = 1.5, .al = [a] { return dF(a->uzunBasSure); }, .ata = [a](const AyarDeger& d) { a->uzunBasSure = (f32)d.f; }}); s.ayarKaydet({.kimlik = "girdi.dokunma_pinch_esik", .kategori = "Dokunmatik", .ad = "Pinch eşiği (px)", .aciklama = "İki parmak birlikte kayarken bu kadarlık mesafe gürültüsü " "zoom'a sızmaz. Büyük = pan sırasında zoom tetiklenmez.", .tip = AyarTip::F32, .varsayilan = dF(6.0), .min = 0, .maks = 40, .al = [a] { return dF(a->pinchEsik); }, .ata = [a](const AyarDeger& d) { a->pinchEsik = (f32)d.f; }}); s.ayarKaydet({.kimlik = "girdi.dokunma_dondur_hassasiyet", .kategori = "Dokunmatik", .ad = "Döndürme hassasiyeti", .aciklama = "Parmak/kalem döndürme hız çarpanı (1 = fareyle aynı).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.1, .maks = 5, .al = [a] { return dF(a->dondurHassasiyet); }, .ata = [a](const AyarDeger& d) { a->dondurHassasiyet = (f32)d.f; }}); s.ayarKaydet({.kimlik = "girdi.dokunma_pan_hassasiyet", .kategori = "Dokunmatik", .ad = "Kaydırma hassasiyeti", .aciklama = "Parmak/kalem pan hız çarpanı (1 = fareyle aynı).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.1, .maks = 5, .al = [a] { return dF(a->panHassasiyet); }, .ata = [a](const AyarDeger& d) { a->panHassasiyet = (f32)d.f; }}); s.ayarKaydet({.kimlik = "girdi.dokunma_hedef_carpan", .kategori = "Dokunmatik", .ad = "Parmak hedef büyütme", .aciklama = "Gizmo tutamaçlarının VURMA alanı parmak girdisinde bu çarpanla " "büyür (görsel boy değişmez). Parmak ucu ~40px, tutamaç 11px → " "büyütmeden ıskalanır. Kalem ve fare etkilenmez (uç hassas). " "1 = büyütme yok.", .tip = AyarTip::F32, .varsayilan = dF(2.2), .min = 1, .maks = 5, .al = [] { return dF(dokunmaHedefCarpan()); }, .ata = [](const AyarDeger& d) { dokunmaHedefCarpan() = (f32)d.f; }}); s.ayarKaydet({.kimlik = "girdi.dokunma_zoom_hassasiyet", .kategori = "Dokunmatik", .ad = "Pinch zoom hassasiyeti", .aciklama = "1 = birebir (parmak arası 2× açılınca mesafe yarıya iner).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.1, .maks = 5, .al = [a] { return dF(a->zoomHassasiyet); }, .ata = [a](const AyarDeger& d) { a->zoomHassasiyet = (f32)d.f; }}); } #ifdef FIKO_CEF void kaydetYardim(AyarSistemi& s) { s.ayarKaydet({.kimlik = "yardim.gpu_hizlandirma", .kategori = "Yardım", .ad = "GPU hızlandırma (yeniden başlat gerekir)", .aciklama = "Yardım panelini GPU'da çiz (D3D11 paylaşımlı doku → Vulkan, " "CPU'ya inmez). Video/WebGL gibi ağır içerikte akıcılık kazandırır; " "statik dokümanda fark etmez. Kapalı = software çizim (varsayılan, " "her sürücüde güvenli). DEĞİŞİKLİK UYGULAMA YENİDEN BAŞLATILINCA " "geçerli (CEF başlangıçta yapılandırılır).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(yardimCefGpuHizli()); }, .ata = [](const AyarDeger& d) { yardimCefGpuHizliAyarla(d.b); }}); } #endif void kaydetMakro(AyarSistemi& s) { s.ayarKaydet({.kimlik = "makro.oneri_aktif", .kategori = "Makro", .ad = "Makro önerisi", .aciklama = "Aynı komut dizisini arka arkaya tekrarlarsan viewport üstünde " "'🔮 Bu N adımı makro yap?' çıkar; kabul edince FikoCAD Lua " "makrosunu kendi yazıp makrolar/ klasörüne kaydeder. Kapalı = " "hiç öneri çıkmaz, komut geçmişi tutulmaz.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(makroOnerisiAktif()); }, .ata = [](const AyarDeger& d) { makroOnerisiAktif() = d.b; }}); s.ayarKaydet({.kimlik = "makro.min_tekrar", .kategori = "Makro", .ad = "En az tekrar sayısı", .aciklama = "Bir komut dizisinin makro önerilmesi için arka arkaya kaç kez " "geçmesi gerektiği. 2 = ikinci tekrarda öner (hassas), 3 = daha " "emin ol (az öneri).", .tip = AyarTip::Int, .varsayilan = dInt(2), .min = 2, .maks = 5, .al = [] { return dInt(makroOnerisiMinTekrar()); }, .ata = [](const AyarDeger& d) { makroOnerisiMinTekrar() = (int)std::max(2, d.i); }}); } void kaydetMenuOgrenme(AyarSistemi& s) { s.ayarKaydet({.kimlik = "menu.ogrenme_aktif", .kategori = "Bağlam Menüsü", .ad = "Menü öğrenmesi", .aciklama = "Çalıştırdığın komutlar duruma göre (yüz/kenar/gövde/boşluk) " "sayılır; sağ-tık menüsünde 'son kullandığın' + 'sık " "kullandığın' ve en üstte '🔁 Tekrarla' çıkar. Kapalı = menü " "hep aynı sırada (eğitim/demo).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(menuOgrenmeAktif()); }, .ata = [](const AyarDeger& d) { menuOgrenmeAktif() = d.b; }}); // Sıfırlama Bool ayar olarak: açığa çekilince siler + kendini kapatır (AyarSistemi'nde // "buton" tipi yok; ayarKaydet al/ata sözleşmesiyle en yalın çözüm). s.ayarKaydet({.kimlik = "menu.ogrenme_sifirla", .kategori = "Bağlam Menüsü", .ad = "Öğrenilenleri sıfırla", .aciklama = "İşaretle → tüm komut kullanım geçmişi silinir (geri alınamaz). " "Kutucuk kendiliğinden kapanır.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(false); }, .ata = [](const AyarDeger& d) { if (d.b) komutOgrenmeSifirla(); }}); } void kaydetFeatureOnizleme(AyarSistemi& s) { FeatureOnizlemeAyar* o = &featureOnizlemeAyar(); s.ayarKaydet({.kimlik = "feature.onizleme_ghost", .kategori = "Part Design", .ad = "Ghost önizleme", .aciklama = "Taslak feature'ın sonucu yarı-saydam gösterilir (✔ Tamam kalıcı yapar).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [o] { return dBool(o->aktif); }, .ata = [o](const AyarDeger& d) { o->aktif = d.b; }}); s.ayarKaydet({.kimlik = "feature.onizleme_saydamlik", .kategori = "Part Design", .ad = "Önizleme saydamlığı", .aciklama = "Taslak sonuç saydamlığı (düşük = daha şeffaf).", .tip = AyarTip::F32, .varsayilan = dF(0.4), .min = 0.1, .maks = 0.9, .al = [o] { return dF(o->saydamlik); }, .ata = [o](const AyarDeger& d) { o->saydamlik = (f32)d.f; }}); } void kaydetDogrudan(AyarSistemi& s) { DogrudanAyar* d = &dogrudanAyar(); s.ayarKaydet({.kimlik = "dogrudan.ok_boy", .kategori = "Doğrudan Modelleme", .ad = "Push/Pull ok boyutu", .aciklama = "Yüz seçince çıkan itme-çekme okunun uzunluğu (kamera mesafesi çarpanı).", .tip = AyarTip::F32, .varsayilan = dF(0.09), .min = 0.03, .maks = 0.30, .al = [d] { return dF(d->okBoyOran); }, .ata = [d](const AyarDeger& v) { d->okBoyOran = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.arama_menu", .kategori = "Doğrudan Modelleme", .ad = "Arama menüsü (sağ-tık)", .aciklama = "DM'de yüz/kenara sağ-tık → arama kutulu bağlam menüsü (seçili nesneye " "göre komutlar). Kapatınca eski radyal halka menüsü açılır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->aramaMenu); }, .ata = [d](const AyarDeger& v) { d->aramaMenu = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.arama_menu_ozellik", .kategori = "Doğrudan Modelleme", .ad = "Arama menüsünde özellik bandı", .aciklama = "Sağ-tık arama menüsünde, arama boşken kutunun hemen altında kompakt " "grafik özellik satırı: seçili yüz/gövde rengi, palet, saydamlık, " "gizle ve kalıcı kimlik (KYA). Yazmaya başlayınca bant gizlenir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->aramaMenuOzellik); }, .ata = [d](const AyarDeger& v) { d->aramaMenuOzellik = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.oneri_cipi", .kategori = "Doğrudan Modelleme", .ad = "Akıllı seçim öneri çipi", .aciklama = "Tek yüz/kenar seçince viewport altında '+6 aynı ölçüde yüz seç' " "çipi belirir (delik/fillet/koplanar…). Tıkla → menü açmadan " "hepsini seç. Topolojiden türetilir; öneri yoksa görünmez.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->oneriCipi); }, .ata = [d](const AyarDeger& v) { d->oneriCipi = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.async_apply", .kategori = "Doğrudan Modelleme", .ad = "Arka planda uygula (async)", .aciklama = "Fillet/pah/it-çek OCCT hesabı arka planda koşar: bırakışta arayüz " "DONMAZ, hayalet önizleme sonuç inene dek kalır (CATIA hissi). " "Kapatınca eski senkron yol (bırakışta bekler).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->asyncApply); }, .ata = [d](const AyarDeger& v) { d->asyncApply = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.tek_workbench", .kategori = "Doğrudan Modelleme", .ad = "DM tek workbench", .aciklama = "DM her şeyin merkezi: sağ-tık bağlam menüleri Part Design " "zenginliğiyle gelir (it/çek, cep, eskiz, keskin kenar...), " "workbench gezintisi gerekmez. Kademeli entegrasyonun ana " "anahtarı. Kapalı → eski çoklu-workbench davranışı.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->tekWorkbench); }, .ata = [d](const AyarDeger& v) { d->tekWorkbench = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.zincir_onizleme", .kategori = "Doğrudan Modelleme", .ad = "Fillet/pah zincir etki önizlemesi", .aciklama = "Fillet/pah penceresi açıkken OCCT'nin teğet devamıyla KIRACAĞI " "tüm kenarlar turuncu kalın çizgiyle gösterilir — tek kenar seçsen " "de zincirin tamamı baştan belli olur. Kapalı → yalnız seçilen " "kenar vurgusu (eski görünüm).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->zincirOnizleme); }, .ata = [d](const AyarDeger& v) { d->zincirOnizleme = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.mevcut_feature_iptal", .kategori = "Doğrudan Modelleme", .ad = "Mevcut feature düzenlemede × iptal", .aciklama = "Var olan bir feature'ı (fillet R, pah, it/çek) push/pull ile düzenlerken " "de hayalet etikete × iptal butonu belirir: async sonuç inmeden basınca " "parametre eski değerine döner (geometri zaten değişmemiştir → güvenli). " "Kapatınca × yalnız YENİ feature'da görünür (eski davranış).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->mevcutFeatureIptal); }, .ata = [d](const AyarDeger& v) { d->mevcutFeatureIptal = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.kalici_kimlik", .kategori = "Doğrudan Modelleme", .ad = "Kalıcı topolojik kimlik (KYA)", .aciklama = "Yüz/kenar/nokta'ya kalıcı u64 etiket verir; feature işlemleri boyunca " "TAŞINIR (CATIA CGM / Parasolid ruhu) → ordinal kaysa da 'aynı yüz' string " "ile hep seçilebilir + dosyada korunur. Devasa modelde O(N) etiketleme + " "serileştirme yükü olduğundan varsayılan KAPALI.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(geometri::kaliciKimlikAcikMi()); }, .ata = [](const AyarDeger& v) { geometri::kaliciKimlikAyarla(v.b); }}); s.ayarKaydet({.kimlik = "dogrudan.coklu_kontur_max", .kategori = "Doğrudan Modelleme", .ad = "Çoklu it/çek önizleme tavanı", .aciklama = "Çok yüz seçiliyken canlı kontur önizlemesi en çok bu kadar yüz için " "örneklenir (devasa koplanar seçimde kare hızını korur). Tavanın " "üstünde önizleme çizilmez; uygulama yine TÜM seçili yüzlere yapılır.", .tip = AyarTip::F32, .varsayilan = dF(64.0), .min = 4, .maks = 512, .al = [d] { return dF(d->cokluKonturMax); }, .ata = [d](const AyarDeger& v) { d->cokluKonturMax = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.sil_yuz_kaldir", .kategori = "Doğrudan Modelleme", .ad = "Delete = Yüz Kaldır", .aciklama = "Doğrudan Modelleme'de yüz seçiliyken Delete seçili yüz(ler)i kaldırıp " "komşuları uzatarak kapatır (Remove Face/heal — fillet, pah, delik geri " "alma). Kapatınca Delete eski davranışla gövdeyi siler.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->silYuzKaldir); }, .ata = [d](const AyarDeger& v) { d->silYuzKaldir = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.datum_arkada", .kategori = "Doğrudan Modelleme", .ad = "Datum'u arkaya al (DM)", .aciklama = "Doğrudan Modelleme'de düzlem/eksen/origin yön ve düzlemleri SEÇİLEBİLİR " "kalır, ancak üstünden geçen model kenarı/noktası önce gelir → datum " "çizgisi model kenarının hover'ını çalmaz. Kapalı → datum üstte kazanır. " "Yalnız DM workbench'ini etkiler.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->datumArkada); }, .ata = [d](const AyarDeger& v) { d->datumArkada = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.tasi_mesafe", .kategori = "Doğrudan Modelleme", .ad = "Yüz Taşı mesafesi (mm)", .aciklama = "Yüz Taşı (Move Face) komutunun öteleme mesafesi. Yön: seçili kenar " "(varsa) yoksa yüzün normali; eğik yönde taşımada komşu duvarlar " "esner (push/pull'un genellemesi).", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = 0.1, .maks = 500.0, .al = [d] { return dF(d->tasiMesafe); }, .ata = [d](const AyarDeger& v) { d->tasiMesafe = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.yuz_tasi_gizmo", .kategori = "Doğrudan Modelleme", .ad = "Yüz Taşı interaktif gizmo", .aciklama = "Yüz Taşı komutu düz yüzde 3-eksen (X/Y/Z) tutamaç triadı açar — bir " "ok sürüklenince yüz o yön boyunca canlı önizlenir, bırakışta parametrik " "yuz_tasi feature'ı uygulanır. Kapatınca sabit-mesafe tek-atış davranışı.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->yuzTasiGizmo); }, .ata = [d](const AyarDeger& v) { d->yuzTasiGizmo = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.gsd_gizmo", .kategori = "Doğrudan Modelleme", .ad = "GSD Yüzey offset gizmosu", .aciklama = "Bir GSD Yüzey düğümü seçiliyken yüzey normali boyunca offset oku belirir " "— tut-sürükle canlı paralel yüzey önizler, bırakışta parametrik yuzeyOffset " "feature'ı ekler (ağaçtan mesafe düzenlenebilir). Kapatınca yalnız menü/pencere yolu.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->gsdGizmoAcik); }, .ata = [d](const AyarDeger& v) { d->gsdGizmoAcik = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.gsd_offset_mesafe", .kategori = "Doğrudan Modelleme", .ad = "GSD offset varsayılan mesafe (mm)", .aciklama = "GSD Yüzey offset gizmosunun varsayılan mesafesi (sürükleme ya da sayı yazma " "bu değeri geçersiz kılar).", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = -1000.0, .maks = 1000.0, .al = [d] { return dF(d->gsdOffsetMesafe); }, .ata = [d](const AyarDeger& v) { d->gsdOffsetMesafe = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.gsd_sisir_grid", .kategori = "Doğrudan Modelleme", .ad = "GSD Şişir ızgara çözünürlüğü", .aciklama = "Şişir modunda yüzeye atılan pick edilebilir nokta ızgarasının kenar başına " "nokta sayısı (Plasticity çok-noktalı şişirme). Bir nokta seçilince şişirme " "o noktadan olur; seçilmezse yüzey merkezinden (eski davranış).", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = 2.0, .maks = 64.0, .al = [d] { return dF(d->gsdSisirGridBol); }, .ata = [d](const AyarDeger& v) { d->gsdSisirGridBol = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.gsd_sisir_yaricap_oran", .kategori = "Doğrudan Modelleme", .ad = "GSD Şişir etki yarıçapı oranı", .aciklama = "Şişirme etki yarıçapı = yüzeyin dünya yarıçapı × bu oran. 1.1 = tüm yüzey " "(tek büyük kubbe, eski davranış). Çok-noktalı şişirmede düşürün (~0.3) → " "her hedef ayrı yerel tepe/çukur olur (kubbeler birleşmez).", .tip = AyarTip::F32, .varsayilan = dF(1.1), .min = 0.05, .maks = 3.0, .al = [d] { return dF(d->gsdSisirYaricapOran); }, .ata = [d](const AyarDeger& v) { d->gsdSisirYaricapOran = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.kenar_gizmo", .kategori = "Doğrudan Modelleme", .ad = "Kenar gizmosu (⟀ eğ + ⇱ uzat)", .aciklama = "Kenar kipinde tek kenar seçilince kenar ortasında eğme yayı " "ve uzatma oku belirir. Kapalı: gizmo çizilmez (radyal halka " "komutları çalışmaya devam eder).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->kenarGizmo); }, .ata = [d](const AyarDeger& v) { d->kenarGizmo = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.kenar_eg_aci", .kategori = "Doğrudan Modelleme", .ad = "Kenardan Eğ varsayılan açısı", .aciklama = "\"Kenardan Eğ\" komutunun ilk uyguladığı açı (derece). " "Feature sonrası özellik panelinden serbestçe değiştirilir.", .tip = AyarTip::F32, .varsayilan = dF(10.0), .min = -80.0, .maks = 80.0, .al = [d] { return dF(d->kenarEgAci); }, .ata = [d](const AyarDeger& v) { d->kenarEgAci = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.kenar_uzat_duzlemde", .kategori = "Doğrudan Modelleme", .ad = "Kenardan Uzat: yüz düzleminde", .aciklama = "Açık: SADECE çekilen kenar hareket eder — seçili yüz kendi " "düzleminde o kenardan uzar, öteki komşu yüz uzak menteşesinden " "eğilir (iki yüzün de diğer kenarları sabit). Kapalı: eski " "davranış — komşu yüz normali boyunca komple itilir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->kenarUzatDuzlemde); }, .ata = [d](const AyarDeger& v) { d->kenarUzatDuzlemde = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.gsd_sisir_sinir_kilit", .kategori = "Doğrudan Modelleme", .ad = "GSD Şişir: bağlı kenarları koru", .aciklama = "Şişirilen yüzeyin SINIR kenarları sabit tutulur → komşu yüzey/" "kenarlara bağlılık kopmaz, iç noktalar gerilerek uzar. Kapalı: " "eski — sınır da şişirmeye katılır (yüzey kenardan ayrılabilir). " "Yeni şişir feature'larına uygulanır; mevcut feature panelden.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->gsdSisirSinirKilit); }, .ata = [d](const AyarDeger& v) { d->gsdSisirSinirKilit = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.gsd_sisir_kilit_derinlik", .kategori = "Doğrudan Modelleme", .ad = "GSD Şişir kilit derinliği", .aciklama = "Sabit tutulan sınır kontrol-noktası halka sayısı: 1 = yalnız " "kenar (C0 bağlılık), 2 = kenar + bir iç halka (yaklaşık " "teğetlik de korunur — geçiş daha yumuşak).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 1.0, .maks = 2.0, .al = [d] { return dF(d->gsdSisirKilitDerinlik); }, .ata = [d](const AyarDeger& v) { d->gsdSisirKilitDerinlik = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.gsd_tek_feature", .kategori = "Doğrudan Modelleme", .ad = "GSD aynı yüzeyde feature güncelle", .aciklama = "Aynı yüzeyde aynı tip gizmo işlemi yeni feature yığmak yerine mevcut " "feature'ı günceller (şişir → hedef ekler, offset/uzat → mesafeyi toplar). " "Kapalı → her sürükleme yeni feature (eski davranış).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->gsdTekFeature); }, .ata = [d](const AyarDeger& v) { d->gsdTekFeature = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.gsd_kaynak_gizle", .kategori = "Doğrudan Modelleme", .ad = "GSD op sonrası kaynağı gizle", .aciklama = "Kaynağı değiştiren GSD işlemi (şişir/offset/uzat/yumuşat/kırp...) sonuç " "üretince kaynak yüzey otomatik gizlenir (üst üste yüzey yığılmaz); feature " "iptal/silinince geri görünür. Kapalı → kaynak görünür kalır (eski davranış).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->gsdKaynakGizle); }, .ata = [d](const AyarDeger& v) { d->gsdKaynakGizle = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.alt_kopyala_tasi", .kategori = "Doğrudan Modelleme", .ad = "Alt+sürükle = kopyala-taşı", .aciklama = "Transform gizmosunda gövde modunda Alt basılıyken sürükleme önce gövdeyi " "KOPYALAR, sürükleme kopyayı taşır (SolidWorks/Fusion kalıbı). Kapalı → " "Alt etkisiz (eski davranış).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->altKopyalaTasi); }, .ata = [d](const AyarDeger& v) { d->altKopyalaTasi = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.cift_tik_akilli", .kategori = "Doğrudan Modelleme", .ad = "Akıllı çift-tık (bağlam-duyarlı)", .aciklama = "Profesyonel CAD çift-tık jesti: YÜZ kipinde çift-tık yüz → o yüzde Sketch " "başlat; KENAR kipinde çift-tık kenar → teğet kenar zinciri seç. Kapalı → " "eski davranış (çift-tık = seç + kameraya sığdır).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->dmCiftTikAkilli); }, .ata = [d](const AyarDeger& v) { d->dmCiftTikAkilli = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.teget_yayilim", .kategori = "Doğrudan Modelleme", .ad = "Teğet yayılımı (Grow: Moving)", .aciklama = "Push/Pull'da seçili yüzün G1-teğet komşularından EŞDEĞER olanlar " "hedefe otomatik katılır (düzlem → aynı yöne bakan düzlemler; silindir → " "eş eksenli + eş yarıçaplı silindirler): seam/kenar ile bölünmüş yüzey " "tek parça gibi hareket eder; önizlemede amber çizilir. " "Fillet/pah komşuları bilerek DIŞARIDA (aynı mesafe onları ötelemez, " "yarıçaplarını değiştirirdi). Kapalı → yalnız seçili yüz(ler) hareket eder.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->tegetYayilim); }, .ata = [d](const AyarDeger& v) { d->tegetYayilim = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.teget_blend_korur", .kategori = "Doğrudan Modelleme", .ad = "Teğet yayılımı: blend'i koru", .aciklama = "Teğet yayılımı açıkken, hareket eden yüze teğet yuvarlak blend " "(fillet) SÖKÜLÜR, öteleme yapılır, sonra AYNI yarıçapla yeniden " "KURULUR — fillet öteleme boyunca korunur (SpaceClaim kalıbı). " "Kapalıyken blend hedefe hiç katılmaz, komşu olarak esner. " "Herhangi bir adım başarısızsa sessizce düz it/çek'e düşülür.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->tegetBlendKorur); }, .ata = [d](const AyarDeger& v) { d->tegetBlendKorur = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.teget_aci_tol", .kategori = "Doğrudan Modelleme", .ad = "Teğet yayılımı açı toleransı (°)", .aciklama = "İki yüzün ortak kenarda 'teğet' sayılması ve normallerin hizalı " "kabul edilmesi için izin verilen sapma. Büyütmek yayılımı genişletir " "(kazara komşu yüzler de taşınabilir).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.01, .maks = 45.0, .al = [d] { return dF(d->tegetAciTol); }, .ata = [d](const AyarDeger& v) { d->tegetAciTol = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.push_pull_hiza_snap", .kategori = "Doğrudan Modelleme", .ad = "Push/Pull snap (hizalama + kademe)", .aciklama = "Sürüklerken mesafe, gövdedeki komşu PARALEL yüz düzlemlerine ve sıfıra " "mıknatıslanır (SpaceClaim 'Ruler' karşılığı) — kilitlenince etiket " "yeşile döner ve ⇥ gösterir. Shift basılıyken kademe (snap mesafesi) " "snap'i öne geçer; klavyeden yazılan değer her ikisini de ezer. " "Kapalı → mesafe tamamen serbest (Shift de etkisiz) = eski davranış.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->pushPullHizaSnap); }, .ata = [d](const AyarDeger& v) { d->pushPullHizaSnap = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.push_pull_snap_px", .kategori = "Doğrudan Modelleme", .ad = "Hizalama snap yakalama alanı (px)", .aciklama = "Mesafenin bir hizalama adayına kilitlenmesi için ekranda kalması " "gereken piksel yakınlığı. Piksel cinsinden olduğu için yakınlaşınca " "hassaslaşır, uzaklaşınca kolay yakalanır.", .tip = AyarTip::F32, .varsayilan = dF(8.0), .min = 1.0, .maks = 40.0, .al = [d] { return dF(d->pushPullSnapPx); }, .ata = [d](const AyarDeger& v) { d->pushPullSnapPx = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.teget_yaricap_tol", .kategori = "Doğrudan Modelleme", .ad = "Teğet yayılımı yarıçap/eksen toleransı (mm)", .aciklama = "Silindirik yüzde yayılımın 'aynı silindirin parçası' sayması için " "izin verilen yarıçap farkı ve eksen kaçıklığı. Seam/kenar ile " "bölünmüş tek silindirik yüzeyi tek parça gibi toplar.", .tip = AyarTip::F32, .varsayilan = dF(0.001), .min = 1e-5, .maks = 1.0, .al = [d] { return dF(d->tegetYaricapTol); }, .ata = [d](const AyarDeger& v) { d->tegetYaricapTol = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.teget_tohum_max", .kategori = "Doğrudan Modelleme", .ad = "Teğet yayılımı tohum tavanı", .aciklama = "Yayılım en çok bu kadar seçili yüz için koşar; üstünde atlanır. " "Her tohum için topolojik ancestors haritası kurulur — devasa modelde " "çok seçimle birlikte seçim değişimini yavaşlatabilir.", .tip = AyarTip::F32, .varsayilan = dF(8.0), .min = 1.0, .maks = 128.0, .al = [d] { return dF(d->tegetTohumMax); }, .ata = [d](const AyarDeger& v) { d->tegetTohumMax = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.blok_kaydir_mesafe", .kategori = "Doğrudan Modelleme", .ad = "Blok Kaydır mesafesi (mm)", .aciklama = "Blok Kaydır (Move Region) komutunun öteleme mesafesi. Yön: seçili kenar " "taban düzlemine izdüşürülür (yoksa taban U teğeti). Çıkıntı taban boyunca " "rijit kayar (cikinti_kaydir feature — ağaçtan tasiX/Y/Z düzenlenebilir).", .tip = AyarTip::F32, .varsayilan = dF(10.0), .min = 0.1, .maks = 1000.0, .al = [d] { return dF(d->blokKaydirMesafe); }, .ata = [d](const AyarDeger& v) { d->blokKaydirMesafe = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.snap_aci", .kategori = "Doğrudan Modelleme", .ad = "Döndürme snap adımı (°)", .aciklama = "Transform gizmosunda döndürme yayı sürüklenirken Shift basılıysa açı " "bu adıma yuvarlanır (Plasticity açı-snap). Örn. 15° = 24 kademe.", .tip = AyarTip::F32, .varsayilan = dF(15.0), .min = 1.0, .maks = 90.0, .al = [d] { return dF(d->snapAci); }, .ata = [d](const AyarDeger& v) { d->snapAci = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.snap_mesafe", .kategori = "Doğrudan Modelleme", .ad = "Öteleme snap adımı (mm)", .aciklama = "Transform gizmosunda eksen oku sürüklenirken Shift basılıysa mesafe bu " "grid adımına yuvarlanır (Plasticity grid-snap).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.01, .maks = 100.0, .al = [d] { return dF(d->snapMesafe); }, .ata = [d](const AyarDeger& v) { d->snapMesafe = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.import_ayri_body", .kategori = "Doğrudan Modelleme", .ad = "STEP: her solid ayrı Body", .aciklama = "STEP içe aktarımında birden çok üst-seviye katı varsa HER biri ayrı " "PartBody olur (CATIA assembly — her gövde bağımsız feature kapsamı). " "Kapalı → hepsi tek import-body'sinde toplanır (varsayılan).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [d] { return dBool(d->importAyriBody); }, .ata = [d](const AyarDeger& v) { d->importAyriBody = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.gizmo_compass_oncelik", .kategori = "Doğrudan Modelleme", .ad = "Gizmo compass önceliği", .aciklama = "Birleşik transform gizmosu bir gövdeyi yönetirken (gövde seçili) CATIA " "compass obje-taşımayı gizmoya bırakır; yalnız navigasyon compass'ı " "kalır. Kapatınca compass da eskisi gibi gövde taşıyabilir (çift araç).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->gizmoCompassOncelik); }, .ata = [d](const AyarDeger& v) { d->gizmoCompassOncelik = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.dondur_rijit", .kategori = "Doğrudan Modelleme", .ad = "Döndürme yayı: rijit döndür", .aciklama = "Gizmo döndürme yayı (yüz seçili) çıkıntının TAMAMINI keyfi eksen " "etrafında rijit döndürür (önizlemeyle birebir eşleşir). Kapalı → eski " "draft davranışı (kalıp çıkış açısı; duvarı tabandan açılandırır). " "Bu ayar yeni yuz_dondur feature'ının 'rijit' parametresini besler — " "sonradan ürün ağacından feature bazında değiştirilebilir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->dondurRijit); }, .ata = [d](const AyarDeger& v) { d->dondurRijit = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.push_pull_oto_ok", .kategori = "Doğrudan Modelleme", .ad = "Push/Pull oku otomatik belirsin", .aciklama = "Doğrudan Modelleme'de seçilen her yüzde it/çek oku OTOMATİK belirir " "(ok o yüze 'zıplar'). Kapatınca ok kendiliğinden çıkmaz; yalnız Ctrl " "basılıyken deliberatif olarak görünür → yüz seçimi/ölçüm serbest kalır, " "kazara it/çek olmaz.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->pushPullOtoOk); }, .ata = [d](const AyarDeger& v) { d->pushPullOtoOk = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.yuz_tasi_oto", .kategori = "Doğrudan Modelleme", .ad = "Transform gizmosu otomatik belirsin", .aciklama = "Doğrudan Modelleme'de tek düz yüz (veya gövde) seçilince döndür/taşı " "transform gizmosu OTOMATİK belirir (seçilen yere 'zıplar'). Kapatınca " "gizmo kendiliğinden çıkmaz; yalnız Ctrl basılıyken deliberatif görünür " "→ yüz/gövde seçimi serbest kalır, kazara döndürme/taşıma olmaz.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->yuzTasiOto); }, .ata = [d](const AyarDeger& v) { d->yuzTasiOto = v.b; }}); static const char* gizmoYonModAd[2] = {"Yüz (U/V/N)", "Dünya (X/Y/Z)"}; s.ayarKaydet({.kimlik = "dogrudan.gizmo_yon_mod", .kategori = "Doğrudan Modelleme", .ad = "Gizmo yönelim modu", .aciklama = "Transform (taşı/döndür) gizmosunun varsayılan yönelim modu " "(0=Yüz U/V/N, 1=Dünya X/Y/Z). W tuşuyla değiştirilebilir.", .tip = AyarTip::Secenek, .varsayilan = dMetin(gizmoYonModAd[0]), .secenekler = {gizmoYonModAd[0], gizmoYonModAd[1]}, .al = [d] { return dMetin(gizmoYonModAd[d->gizmoYonMod == 1 ? 1 : 0]); }, .ata = [d](const AyarDeger& v) { d->gizmoYonMod = (v.metin == gizmoYonModAd[1]) ? 1 : 0; }}); s.ayarKaydet({.kimlik = "dogrudan.secimi_koru", .kategori = "Doğrudan Modelleme", .ad = "İşlem sonrası seçimi koru", .aciklama = "İt/çek uygulandığında ötelenen yüz(ler) yeni gövdede otomatik " "yeniden seçilir — ok hemen belirir, aynı yüz art arda itilip " "çekilebilir. Kapatınca işlem sonrası seçim boş kalır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->secimiKoru); }, .ata = [d](const AyarDeger& v) { d->secimiKoru = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.glow", .kategori = "Doğrudan Modelleme", .ad = "Gizmo glow", .aciklama = "Tutamaç/ok hover'ında neon parıltı efekti (kapatınca düz çizgi).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [d] { return dBool(d->glowAcik); }, .ata = [d](const AyarDeger& v) { d->glowAcik = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.glow_guc", .kategori = "Doğrudan Modelleme", .ad = "Glow şiddeti", .aciklama = "Gizmo neon parıltısının yoğunluğu (glow açıkken).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.2, .maks = 2.5, .al = [d] { return dF(d->glowGuc); }, .ata = [d](const AyarDeger& v) { d->glowGuc = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.fillet_hassas", .kategori = "Doğrudan Modelleme", .ad = "Fillet sürükleme hassasiyeti", .aciklama = "Kenar fillet/pah sürüklemesinde yarıçap değişim hızı.", .tip = AyarTip::F32, .varsayilan = dF(1.2), .min = 0.3, .maks = 3.0, .al = [d] { return dF(d->filletHassas); }, .ata = [d](const AyarDeger& v) { d->filletHassas = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.kabuk_kalinlik", .kategori = "Doğrudan Modelleme", .ad = "Kabuk kalınlığı", .aciklama = "Kabuk/Shell komutunun varsayılan et kalınlığı (mm).", .tip = AyarTip::F32, .varsayilan = dF(2.0), .min = 0.1, .maks = 50.0, .al = [d] { return dF(d->kabukKalinlik); }, .ata = [d](const AyarDeger& v) { d->kabukKalinlik = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.emboss_mesafe", .kategori = "Doğrudan Modelleme", .ad = "Sketch kabart/oy mesafesi", .aciklama = "Sketch Kabart/Oy (sketch-on-surface) varsayılan prizma mesafesi (mm). " "Kabart dışa, oy içe uygular.", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.1, .maks = 50.0, .al = [d] { return dF(d->embossMesafe); }, .ata = [d](const AyarDeger& v) { d->embossMesafe = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.itcek_mesafe", .kategori = "Doğrudan Modelleme", .ad = "Yüz it/çek mesafesi", .aciklama = "Yüz İt/Çek (numeric push/pull) varsayılan mesafe (mm). + dışa uzat, " "− içe oy. Düz/silindir/küre/koni yüzlerde çalışır (drag yerine tam değer).", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = -50.0, .maks = 50.0, .al = [d] { return dF(d->itCekMesafe); }, .ata = [d](const AyarDeger& v) { d->itCekMesafe = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.kalinlik_mesafe", .kategori = "Doğrudan Modelleme", .ad = "Kalınlık offset", .aciklama = "Kalınlık/Thickness komutunun varsayılan offset mesafesi (mm, +büyüt/−küçült).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = -20.0, .maks = 20.0, .al = [d] { return dF(d->kalinlikMesafe); }, .ata = [d](const AyarDeger& v) { d->kalinlikMesafe = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.fillet_yaricap", .kategori = "Doğrudan Modelleme", .ad = "Yuvarlat/Pah yarıçap", .aciklama = "Yuvarlat/Pah komutunun (menü) varsayılan yarıçap/mesafesi (mm).", .tip = AyarTip::F32, .varsayilan = dF(2.0), .min = 0.1, .maks = 50.0, .al = [d] { return dF(d->filletYaricap); }, .ata = [d](const AyarDeger& v) { d->filletYaricap = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.dizi_adet", .kategori = "Doğrudan Modelleme", .ad = "Dairesel dizi adedi", .aciklama = "Dairesel Dizi komutunun varsayılan kopya sayısı.", .tip = AyarTip::F32, .varsayilan = dF(6.0), .min = 2.0, .maks = 64.0, .al = [d] { return dF(d->diziAdet); }, .ata = [d](const AyarDeger& v) { d->diziAdet = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.dizi_aci", .kategori = "Doğrudan Modelleme", .ad = "Dairesel dizi açısı", .aciklama = "Dairesel Dizi komutunun varsayılan toplam açısı (derece, 360=tam tur).", .tip = AyarTip::F32, .varsayilan = dF(360.0), .min = 10.0, .maks = 360.0, .al = [d] { return dF(d->diziAci); }, .ata = [d](const AyarDeger& v) { d->diziAci = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.dizi_lin_mesafe", .kategori = "Doğrudan Modelleme", .ad = "Doğrusal dizi aralığı", .aciklama = "Doğrusal Dizi komutunun varsayılan kopya aralığı (mm).", .tip = AyarTip::F32, .varsayilan = dF(20.0), .min = 0.5, .maks = 500.0, .al = [d] { return dF(d->diziLinMesafe); }, .ata = [d](const AyarDeger& v) { d->diziLinMesafe = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.draft_aci", .kategori = "Doğrudan Modelleme", .ad = "Draft açısı", .aciklama = "Draft (kalıp çıkış açısı) komutunun varsayılan açısı (derece).", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = 0.5, .maks = 45.0, .al = [d] { return dF(d->draftAci); }, .ata = [d](const AyarDeger& v) { d->draftAci = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.tutamac_boy", .kategori = "Doğrudan Modelleme", .ad = "Tutamaç boyutu", .aciklama = "Gizmo tutamaçlarının (fillet R/C simgesi, push/pull ok dairesi) boyut çarpanı.", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.6, .maks = 2.0, .al = [d] { return dF(d->tutamacBoy); }, .ata = [d](const AyarDeger& v) { d->tutamacBoy = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.secim_tol", .kategori = "Doğrudan Modelleme", .ad = "Koplanar seçim toleransı", .aciklama = "Alt+click koplanar/paralel yüz seçiminde normal açı toleransı (derece).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.1, .maks = 15.0, .al = [d] { return dF(d->secimTolDeg); }, .ata = [d](const AyarDeger& v) { d->secimTolDeg = (f32)v.f; }}); s.ayarKaydet({.kimlik = "dogrudan.silindir_min_r", .kategori = "Doğrudan Modelleme", .ad = "Silindir min yarıçap", .aciklama = "Silindirik push/pull'da izin verilen en küçük yarıçap (çap-offset alt sınırı).", .tip = AyarTip::F32, .varsayilan = dF(0.05), .min = 0.01, .maks = 1.0, .al = [d] { return dF(d->silindirMinR); }, .ata = [d](const AyarDeger& v) { d->silindirMinR = (f32)v.f; }}); // ---- Gizmo çember toggle'leri ---- s.ayarKaydet({.kimlik = "dogrudan.gizmo_cevre_onizleme", .kategori = "Doğrudan Modelleme", .ad = "Gizmo çevresi önizleme", .aciklama = "Tutamaçların etrafındaki yardımcı çemberler (toggle: Ctrl+G).", .tip = AyarTip::Bool, .varsayilan = dBool(false), // BAŞLANGIÇ KAPALI .al = [] { return dBool(dogrudanAyar().gizmoCevreOnizleme); }, .ata = [](const AyarDeger& v) { dogrudanAyar().gizmoCevreOnizleme = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.yuz_tasi_cevre_goster", .kategori = "Doğrudan Modelleme", .ad = "Yüz Taşı çevresi göster", .aciklama = "Push/Pull tutamaçların arka plan çember önizlemesi.", .tip = AyarTip::Bool, .varsayilan = dBool(false), // BAŞLANGIÇ KAPALI .al = [] { return dBool(dogrudanAyar().yuzTasiCevreGoster); }, .ata = [](const AyarDeger& v) { dogrudanAyar().yuzTasiCevreGoster = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.yuz_tasi_dondurme_yay", .kategori = "Doğrudan Modelleme", .ad = "Yüz Taşı döndürme yayları", .aciklama = "Yüz Taşı gizmo'ndaki U/V/N eksenlerine dönen halka/yay önizlemeleri.", .tip = AyarTip::Bool, .varsayilan = dBool(true), // BAŞLANGIÇ AÇIK .al = [] { return dBool(dogrudanAyar().yuzTasiDondurmeYay); }, .ata = [](const AyarDeger& v) { dogrudanAyar().yuzTasiDondurmeYay = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.fillet_cevre_goster", .kategori = "Doğrudan Modelleme", .ad = "Fillet çevresi göster", .aciklama = "Kenar fillet tutamaçlarının önizleme çemberleri.", .tip = AyarTip::Bool, .varsayilan = dBool(false), // BAŞLANGIÇ KAPALI .al = [] { return dBool(dogrudanAyar().filletCevreGoster); }, .ata = [](const AyarDeger& v) { dogrudanAyar().filletCevreGoster = v.b; }}); s.ayarKaydet({.kimlik = "dogrudan.kenar_fillet_cevre", .kategori = "Doğrudan Modelleme", .ad = "Kenar fillet çevresi", .aciklama = "Fillet tutamaçların ek çember önizlemeleri (toggle).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(dogrudanAyar().kenarFilletCevre); }, .ata = [](const AyarDeger& v) { dogrudanAyar().kenarFilletCevre = v.b; }}); } void kaydetNavGhost(AyarSistemi& s) { NavGhostDurum* g = &navGhostGlobal(); s.ayarKaydet({.kimlik = "navghost.aktif", .kategori = "Kamera", .ad = "Navigasyon ghost'u", .aciklama = "Döndür/pan/zoom sırasında CATIA tarzı tel-küre / ok göstergesi.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [g] { return dBool(g->aktif); }, .ata = [g](const AyarDeger& d) { g->aktif = d.b; }}); s.ayarKaydet({.kimlik = "navghost.boyut", .kategori = "Kamera", .ad = "Ghost boyutu", .aciklama = "Tel-küre yarıçapı (ekran-göreli, 1 = varsayılan).", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.3, .maks = 2.5, .al = [g] { return dF(g->boyut); }, .ata = [g](const AyarDeger& d) { g->boyut = (f32)d.f; }}); s.ayarKaydet({.kimlik = "navghost.opaklik", .kategori = "Kamera", .ad = "Ghost opaklığı", .aciklama = "Göstergenin genel saydamlığı.", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.2, .maks = 1.0, .al = [g] { return dF(g->opaklik); }, .ata = [g](const AyarDeger& d) { g->opaklik = (f32)d.f; }}); s.ayarKaydet({.kimlik = "kamera.vizyon_kupu", .kategori = "Kamera", .ad = "ViewCube", .aciklama = "Sağ üstte yönlü küp — yüz/kenar/köşeye tıkla → görünüşe snap.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(vizyonKupuAktif()); }, .ata = [](const AyarDeger& d) { vizyonKupuAktif() = d.b; }}); s.ayarKaydet({.kimlik = "kamera.vizyon_kupu_pahli", .kategori = "Kamera", .ad = "ViewCube pahlı köşe/kenar", .aciklama = "FreeCAD tarzı: köşe/kenar pahları tıklanır → çapraz/izometrik bakış.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(vizyonKupuAyar().pahli); }, .ata = [](const AyarDeger& d) { vizyonKupuAyar().pahli = d.b; }}); s.ayarKaydet({.kimlik = "kamera.vizyon_kupu_y_yukari", .kategori = "Kamera", .ad = "ViewCube: Y ekseni yukarı", .aciklama = "Kapalı = Z yukarı (varsayılan), açık = Y yukarı — snap yönelimini eksene göre ayarlar.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(vizyonKupuAyar().yukariEksen == 1); }, .ata = [](const AyarDeger& d) { vizyonKupuAyar().yukariEksen = d.b ? 1 : 0; }}); } void kaydetHizli3d(AyarSistemi& s, UygulamaBaglam& b) { HizliUIDurum* h = &b.hizli; s.ayarKaydet({.kimlik = "hizli3d.ozkutle", .kategori = "Hızlı 3D", .ad = "Özkütle (g/cm³)", .aciklama = "Ağırlık hesabı varsayılan yoğunluğu (2.71 = Al döküm).", .tip = AyarTip::F32, .varsayilan = dF(2.71), .min = 0.1, .maks = 25, .al = [h] { return dF(h->hizliOzkutle); }, .ata = [h](const AyarDeger& d) { h->hizliOzkutle = (f32)d.f; }}); s.ayarKaydet({.kimlik = "hizli3d.kutuk_saydam", .kategori = "Hızlı 3D", .ad = "Kütük dolgu saydamlığı", .aciklama = "Sahnedeki kütük kutusunun dolgu opaklığı (0 = tel).", .tip = AyarTip::F32, .varsayilan = dF(0.15), .min = 0, .maks = 0.6, .al = [h] { return dF(h->hizliKutukSaydam); }, .ata = [h](const AyarDeger& d) { h->hizliKutukSaydam = (f32)d.f; }}); } void kaydetDokum(AyarSistemi& s) { s.ayarKaydet({.kimlik = "dokum.cozunurluk", .kategori = "Döküm", .ad = "Varsayılan çözünürlük", .aciklama = "Yeni döküm simülasyonunda en uzun eksen hücre sayısı.", .tip = AyarTip::Int, .varsayilan = dInt(40), .min = 10, .maks = 100000, .al = [] { return dInt(g_dokumCozunurluk); }, .ata = [](const AyarDeger& d) { g_dokumCozunurluk = (u32)d.i; }}); s.ayarKaydet({.kimlik = "dokum.voxel_kirp", .kategori = "Döküm", .ad = "Voxel görselini parçaya kırp", .aciklama = "Merkez-sınıflaması hücre sayısını yukarı yuvarladığı için " "en dıştaki küpler parçayı aşar (40mm parça + 3mm hücre → " "42mm görsel). Açık: dış yüzler parçanın sınırına oturur. " "Kapalı: eski davranış (ham voxel kafesi).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_dokumVoxelKirp); }, .ata = [](const AyarDeger& d) { g_dokumVoxelKirp = d.b; }}); s.ayarKaydet({.kimlik = "dokum.kapsama_uyari_esik", .kategori = "Döküm", .ad = "Kafes kapsama uyarı eşiği", .aciklama = "Voxel metal hacmi / gerçek parça hacmi bu oranın altına " "düşerse panel UYARIR. Merkez-sınıflaması cidarı hücreden " "ince bölgeyi tamamen kaçırır → geriye kalın göbek kalır ve " "dolum onu doldurup \"%100\" der. 0 = uyarıyı kapat.", .tip = AyarTip::F64, .varsayilan = dF(0.5), .min = 0.0, .maks = 1.0, .al = [] { return dF((f64)g_dokumKapsamaEsik); }, .ata = [](const AyarDeger& d) { g_dokumKapsamaEsik = (f32)d.f; }}); s.ayarKaydet({.kimlik = "dokum.sph_divergence_cozucu", .kategori = "Döküm", .ad = "SPH divergence çözücü (DFSPH)", .aciklama = "ÖLÇÜLDÜ (07-16): ince çözünürlükte hız alanını PATLATIYOR. " "h=2mm dikey cidarda açık: maks hız 98.0 m/s, hücrelerin " "%7.6'sı >5 m/s; kapalı: 7.3 m/s, %0.4 — üstelik %30 daha " "hızlı ve daha az adım. Kaba çözünürlükte (h≥4mm) fark yok. " "Kapalı = varsayılan (ölçülen doğru yol). Açık = SPlisHSPlasH " "kütüphane davranışı (eski).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(g_dokumSphDivergence); }, .ata = [](const AyarDeger& d) { g_dokumSphDivergence = d.b; }}); s.ayarKaydet({.kimlik = "dokum.sph_maks_partikul", .kategori = "Döküm", .ad = "SPH partikül havuzu tavanı", .aciklama = "Emitter'ın yayabileceği en çok partikül. Gereken sayı " "(1.3 × dökülen hacim / partikül hacmi) tavanı aşarsa " "havuz dolunca emitter SUSAR → dökülen hacim kaviteyi " "karşılayamaz ve büyük kalıp asla %100 dolamaz — panel " "artık bu durumda uyarır. Büyütmek bellek/süre ister " "(maliyet ≈ res^3.6).", .tip = AyarTip::Int, .varsayilan = dInt(400000), .min = 10000, .maks = 5000000, .al = [] { return dInt((i64)g_dokumSphMaksPartikul); }, .ata = [](const AyarDeger& d) { g_dokumSphMaksPartikul = (u32)d.i; }}); s.ayarKaydet({.kimlik = "dokum.giris_kutle_pay", .kategori = "Döküm", .ad = "Giriş kütlesi uygula payı", .aciklama = "Girişlerin toplam kütlesi kavite kütlesinden azsa kalıp " "fizik gereği dolamaz (dolum kütle korunumlu). Paneldeki " "\"Uygula\" düğmesi kütleleri kavite × bu çarpana ölçekler " "(pay: besleyici/yolluk kaybı + kuantalama).", .tip = AyarTip::F64, .varsayilan = dF(1.05), .min = 1.0, .maks = 2.0, .al = [] { return dF(g_dokumGirisKutlePay); }, .ata = [](const AyarDeger& d) { g_dokumGirisKutlePay = d.f; }}); s.ayarKaydet({.kimlik = "dokum.giris_uzak_esik_h", .kategori = "Döküm", .ad = "Giriş kavite-dışı uyarı eşiği [×hücre]", .aciklama = "Giriş noktası en yakın metal hücreden bu kadar hücre " "boyundan uzaksa panel uyarır (kuma/dereceye tıklanmış " "giriş → SPH partikülleri kaviteye giremez).", .tip = AyarTip::F64, .varsayilan = dF(2.0), .min = 0.5, .maks = 20.0, .al = [] { return dF(g_dokumGirisUzakEsikH); }, .ata = [](const AyarDeger& d) { g_dokumGirisUzakEsikH = d.f; }}); s.ayarKaydet({.kimlik = "dokum.kapsama_sisme_esik", .kategori = "Döküm", .ad = "Kafes şişme uyarı eşiği", .aciklama = "Voxel metal hacmi / gerçek parça hacmi bu oranı " "AŞARSA panel uyarır: ince plakalar tek koca hücreye " "yapışmış demektir — doluluk %100 görünse de " "görsel/hız temsilîdir (ölçüldü: 15.2 L parça kaba " "kafeste 62.7 L = ×4.1). 0 = kapalı.", .tip = AyarTip::F64, .varsayilan = dF(1.5), .min = 0.0, .maks = 10.0, .al = [] { return dF(g_dokumKapsamaSisme); }, .ata = [](const AyarDeger& d) { g_dokumKapsamaSisme = d.f; }}); s.ayarKaydet({.kimlik = "dokum.cidar_yuzdelik", .kategori = "Döküm", .ad = "Cidar ölçümü alt yüzdeliği", .aciklama = "\"Cidarı ölç\" pratik cidarı örneklerin bu alt " "yüzdeliğinden alır (0.10 = p10). Ham minimum tek " "pah/delik kenarına kilitlenip absürt çözünürlük " "önerisi üretiyordu (ölçüldü: 1.21mm → res 2169). " "0 = eski davranış (ham minimum).", .tip = AyarTip::F64, .varsayilan = dF(0.10), .min = 0.0, .maks = 0.5, .al = [] { return dF(g_dokumCidarYuzdelik); }, .ata = [](const AyarDeger& d) { g_dokumCidarYuzdelik = d.f; }}); s.ayarKaydet({.kimlik = "dokum.porozite_oto_esik", .kategori = "Döküm", .ad = "Porozite eşiğini veriden türet", .aciklama = "Açık: baloncuk izo-eşiği ilk kurulumda dolu hücrelerin " "üst yüzdeliğinden seçilir → yerel baloncuklar (MAGMA " "okuması). Kapalı: sabit %0.5 — ÖLÇÜLDÜ: hücrelerin " "%58'i üstünde kalıp izo-yüzey parçayı kaplıyordu " "(her yer kırmızı). Elle değiştirilen eşik korunur.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_dokumPorOtoEsik); }, .ata = [](const AyarDeger& d) { g_dokumPorOtoEsik = d.b; }}); s.ayarKaydet({.kimlik = "dokum.porozite_esik_yuzdelik", .kategori = "Döküm", .ad = "Porozite oto eşik yüzdeliği", .aciklama = "0.90 = en kötü %10 hücre vurgulanır. Büyüt → daha az, " "daha kritik baloncuk; küçült → daha geniş vurgu.", .tip = AyarTip::F64, .varsayilan = dF(0.90), .min = 0.5, .maks = 0.99, .al = [] { return dF(g_dokumPorYuzdelik); }, .ata = [](const AyarDeger& d) { g_dokumPorYuzdelik = d.f; }}); s.ayarKaydet({.kimlik = "dokum.derece_goster", .kategori = "Döküm", .ad = "Derece görseli (kum döküm)", .aciklama = "Yeni simülasyonda alt/üst derece çerçevesi + kum " "bloklarını sahnede çiz (görsel; fizik etkilenmez). " "Yalnız kum kalıpta çizilir; sim içinden kapatılabilir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_dokumDereceGoster); }, .ata = [](const AyarDeger& d) { g_dokumDereceGoster = d.b; }}); s.ayarKaydet({.kimlik = "dokum.derece_kum_pay", .kategori = "Döküm", .ad = "Derece yan kum payı [mm]", .aciklama = "Parçadan derece iç duvarına yatay kum mesafesi " "(yeni sim varsayılanı; sim içinden değiştirilebilir).", .tip = AyarTip::F64, .varsayilan = dF(50.0), .min = 5.0, .maks = 500.0, .al = [] { return dF(g_dokumDereceKumPay); }, .ata = [](const AyarDeger& d) { g_dokumDereceKumPay = d.f; }}); s.ayarKaydet({.kimlik = "dokum.derece_ust_pay", .kategori = "Döküm", .ad = "Derece üst kum payı [mm]", .aciklama = "Parça üstünden üst derece kum yüzeyine pay (cope).", .tip = AyarTip::F64, .varsayilan = dF(60.0), .min = 5.0, .maks = 500.0, .al = [] { return dF(g_dokumDereceUstPay); }, .ata = [](const AyarDeger& d) { g_dokumDereceUstPay = d.f; }}); s.ayarKaydet({.kimlik = "dokum.derece_alt_pay", .kategori = "Döküm", .ad = "Derece alt kum payı [mm]", .aciklama = "Parça altından alt derece kum tabanına pay (drag).", .tip = AyarTip::F64, .varsayilan = dF(60.0), .min = 5.0, .maks = 500.0, .al = [] { return dF(g_dokumDereceAltPay); }, .ata = [](const AyarDeger& d) { g_dokumDereceAltPay = d.f; }}); s.ayarKaydet({.kimlik = "dokum.derece_duvar", .kategori = "Döküm", .ad = "Derece duvar kalınlığı [mm]", .aciklama = "Derece çerçevesinin profil duvar kalınlığı (görsel).", .tip = AyarTip::F64, .varsayilan = dF(18.0), .min = 2.0, .maks = 80.0, .al = [] { return dF(g_dokumDereceDuvar); }, .ata = [](const AyarDeger& d) { g_dokumDereceDuvar = d.f; }}); s.ayarKaydet({.kimlik = "dokum.derece_tek_parca", .kategori = "Döküm", .ad = "Tek parça derece", .aciklama = "Açık: tek çerçeveli derece (parça konur, kumlanır, " "ters çevrilip kalanı kumlanır — çevirmeli kalıplama). " "Kapalı: klasik alt+üst derece. Yeni sim varsayılanı.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(g_dokumDereceTekParca); }, .ata = [](const AyarDeger& d) { g_dokumDereceTekParca = d.b; }}); s.ayarKaydet({.kimlik = "dokum.derece_kum_saydamlik", .kategori = "Döküm", .ad = "Kum bloğu saydamlığı", .aciklama = "Kum bloklarının görünürlüğü (0 = görünmez, 1 = opak). " "Düşük değer parçayı boğmaz (MAGMA'da kalıp hafiftir); " "derece çerçevesi standart önizleme saydamlığında kalır.", .tip = AyarTip::F64, .varsayilan = dF(0.18), .min = 0.02, .maks = 0.9, .al = [] { return dF(g_dokumDereceKumSaydamlik); }, .ata = [](const AyarDeger& d) { g_dokumDereceKumSaydamlik = d.f; }}); s.ayarKaydet({.kimlik = "dokum.kum_yogunluk", .kategori = "Döküm", .ad = "Kum yoğunluğu [kg/m³]", .aciklama = "Kum ihtiyacı raporunun kg dönüşümü. Yeşil kum ≈ 1550, " "reçineli ≈ 1600, su camı ≈ 1700.", .tip = AyarTip::F64, .varsayilan = dF(1550.0), .min = 800.0, .maks = 2500.0, .al = [] { return dF(g_dokumKumYogunluk); }, .ata = [](const AyarDeger& d) { g_dokumKumYogunluk = d.f; }}); s.ayarKaydet({.kimlik = "dokum.sph_partikul_kaydet", .kategori = "Döküm", .ad = "SPH partikül konumlarını sakla", .aciklama = "Açık: SPH karesi partikül konumunu da saklar → " "\"Partikül bulutu\" görünümü jeti/sıçramayı/çalkantıyı " "gösterir. Kapalı: eski davranış — kare yalnız hücre " "doluluğu taşır, akış 1 hücreye ezilir. " "Bellek: partikül × kare × 20 bayt (31k×60 ≈ 37 MB).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_dokumPartikulKaydet); }, .ata = [](const AyarDeger& d) { g_dokumPartikulKaydet = d.b; }}); s.ayarKaydet({.kimlik = "dokum.sph_partikul_alt_ornek", .kategori = "Döküm", .ad = "Partikül kayıt alt-örneklemesi", .aciklama = "Kayıtta n'de bir partikül saklanır (1 = hepsi). " "Belleği doğrudan böler; çalkantı algısı seyrelir.", .tip = AyarTip::Int, .varsayilan = dInt(1), .min = 1, .maks = 32, .al = [] { return dInt((i64)g_dokumPartikulAltOrnek); }, .ata = [](const AyarDeger& d) { g_dokumPartikulAltOrnek = (u32)d.i; }}); s.ayarKaydet({.kimlik = "dokum.sph_partikul_yaricap_oran", .kategori = "Döküm", .ad = "Partikül blob yarıçap oranı", .aciklama = "Çizilen partikül yarıçapı = hücre boyu × bu oran. " "Büyük = damlalar birleşip sıvı kütlesi gibi görünür; " "küçük = seyrek nokta bulutu.", .tip = AyarTip::F64, .varsayilan = dF(0.30), .min = 0.02, .maks = 1.0, .al = [] { return dF((f64)g_dokumPartikulYaricapOran); }, .ata = [](const AyarDeger& d) { g_dokumPartikulYaricapOran = (f32)d.f; }}); s.ayarKaydet({.kimlik = "dokum.sph_partikul_ciz_alt_ornek", .kategori = "Döküm", .ad = "Partikül çizim alt-örneklemesi", .aciklama = "Çizimde n'de bir partikül çizilir (1 = hepsi). Kayıt " "etkilenmez — yalnız mesh hafifler (scrubber akıcılığı).", .tip = AyarTip::Int, .varsayilan = dInt(1), .min = 1, .maks = 32, .al = [] { return dInt((i64)g_dokumPartikulCizAltOrnek); }, .ata = [](const AyarDeger& d) { g_dokumPartikulCizAltOrnek = (u32)d.i; }}); } void kaydetStrafor(AyarSistemi& s) { auto boyut = [&](const char* kimlik, const char* ad, f64& g, f64 vars) { s.ayarKaydet({.kimlik = kimlik, .kategori = "Strafor", .ad = ad, .aciklama = "Strafor montaj panelinin açılışındaki varsayılan hedef " "parça ölçüsü (mm). Panelde her an değiştirilebilir.", .tip = AyarTip::F64, .varsayilan = dF(vars), .min = 1.0, .maks = 100000.0, .al = [&g] { return dF(g); }, .ata = [&g](const AyarDeger& d) { g = d.f; }}); }; boyut("strafor.hedef_en", "Varsayılan hedef en", g_straforHedefEn, 2500); boyut("strafor.hedef_boy", "Varsayılan hedef boy", g_straforHedefBoy, 1500); boyut("strafor.hedef_yukseklik", "Varsayılan hedef yükseklik", g_straforHedefYuk, 300); s.ayarKaydet({.kimlik = "strafor.gecici_oncelik", .kategori = "Strafor", .ad = "Geçici (artık) kütük öncelikli", .aciklama = "Açık: elde kalan artık kütükler her pozisyonda standart " "bloklardan ÖNCE denenir + boyutlarına göre ek grid seçenekleri " "üretilir (maliyet tasarrufu). Kapalı: yalnız standart yerleşim.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(g_straforGeciciOncelik); }, .ata = [](const AyarDeger& d) { g_straforGeciciOncelik = d.b; }}); s.ayarKaydet({.kimlik = "strafor.varyant_sayisi", .kategori = "Strafor", .ad = "Gösterilecek varyant sayısı", .aciklama = "Kaç montaj seçeneği (kalınlık + taban/oryantasyon varyantı) " "üretilip listelensin. Yüksek = daha çok mantıklı alternatif " "(ince-üst kalınlık, döndürülmüş taban dahil); düşük = yalnız en iyiler.", .tip = AyarTip::Int, .varsayilan = dInt(40), .min = 5, .maks = 200, .al = [] { return dInt(g_straforVaryant); }, .ata = [](const AyarDeger& d) { g_straforVaryant = (u32)d.i; }}); s.ayarKaydet({.kimlik = "strafor.offcut_nesting", .kategori = "Strafor", .ad = "Artık yeniden kullanım (nesting)", .aciklama = "Açık: grid planlarının yanında GİYOTİN offcut-nesting planları da " "üretilir — bir kütükten kesilen artık, aynı planda sonraki parçalarda " "yeniden kullanılır (daha az fire/kütük; karşılığında daha çok " "yapıştırma). Grid planları değişmez, listede birlikte yarışır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_straforOffcutNesting); }, .ata = [](const AyarDeger& d) { g_straforOffcutNesting = d.b; }}); s.ayarKaydet({.kimlik = "strafor.iscilik_agirligi", .kategori = "Strafor", .ad = "İşçilik önceliği (sıralama)", .aciklama = "Seçenek sıralamasında işçiliğin ağırlığı. Büyük → yapıştırıcıyı en az " "uğraştıran plan (az blok + az yapıştırma → grid) öne gelir; çok-parça " "nesting listede kalır ama üstte olmaz. 0 → malzeme-öncelikli (yalnız " "fire/maliyet; nesting öne çıkabilir). Vars. 2 (işçilik-öncelikli).", .tip = AyarTip::F64, .varsayilan = dF(2.0), .min = 0.0, .maks = 10.0, .al = [] { return dF(g_straforIscilikAgirlik); }, .ata = [](const AyarDeger& d) { g_straforIscilikAgirlik = d.f; }}); s.ayarKaydet({.kimlik = "cam.apt_ithal_simulasyon", .kategori = "CAM", .ad = "APT ithalini simülasyonda göster", .aciklama = "Açık: .FikoApt/.apt dosyası içe aktarılınca yol sahneye " "çizilmez; veri/operasyon tutulur ve simülasyon " "penceresinde oynatılır. Kapalı = eski davranış " "(neon-cyan yol düğümü doğrudan sahnede).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_aptIthalSim); }, .ata = [](const AyarDeger& d) { g_aptIthalSim = d.b; }}); s.ayarKaydet({.kimlik = "cam.apt_aktivite_ayir", .kategori = "CAM", .ad = "APT operasyonlarını ayrı ayrı aç", .aciklama = "Açık: .FikoApt içindeki her \"$$ OPERATION NAME\" bloğu " "AYRI bir CAM operasyonu olur — kendi takımı, devri, takım " "ekseni ve yol dilimiyle (web APT tarayıcısı gibi). Kapalı = " "eski davranış: tüm dosya tek operasyon (ilk isim, ilk takım).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(g_aptAktiviteAyir); }, .ata = [](const AyarDeger& d) { g_aptAktiviteAyir = d.b; }}); s.ayarKaydet({.kimlik = "cam.apt_yay_tolerans", .kategori = "CAM", .ad = "APT yay bölümleme toleransı (mm)", .aciklama = "APT'deki CIRCLE/ yayları doğru parçalara bölünürken izin " "verilen maksimum sapma. Küçük değer = daha çok nokta = daha " "pürüzsüz yay ama daha büyük yol.", .tip = AyarTip::F32, .varsayilan = dF(0.01), .min = 0.001, .maks = 1.0, .al = [] { return dF(g_aptYayTolerans); }, .ata = [](const AyarDeger& d) { g_aptYayTolerans = d.f; }}); s.ayarKaydet({.kimlik = "cam.sim_sahne_gorsel", .kategori = "CAM", .ad = "Simülasyonda sahne görseli", .aciklama = "Açık: CAM simülasyonu takım yolunu 3B sahneye çizer " "(soluk tüm yol + parlak geçilen yol) ve takımı poz " "boyunca hareket ettirir. Büyük yolda kapatılabilir " "(geçilen yol yenilemesi O(poz)).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(camSimSahneGorselAl()); }, .ata = [](const AyarDeger& d) { camSimSahneGorselAta(d.b); }}); s.ayarKaydet({.kimlik = "cam.sim_tum_yol", .kategori = "CAM", .ad = "Simülasyonda tüm yolu göster", .aciklama = "Açık: takım yolunun TAMAMI baştan çizili durur (ilerleme " "takımın konumundan okunur). Kapalı (varsayılan): yalnız " "geçilen kısım çizilir — yol oynatıldıkça açılır.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(camSimTumYolAl()); }, .ata = [](const AyarDeger& d) { camSimTumYolAta(d.b); }}); s.ayarKaydet({.kimlik = "cam.sim_yol_goster", .kategori = "CAM", .ad = "Simülasyonda takım yolunu göster", .aciklama = "Kapalı: yol çizgileri 3B sahnede çizilmez. Takımla birlikte " "kapatılırsa sahnede yalnız oyulmuş kütük kalır (Sadece Kütük modu).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(camSimYolGosterAl()); }, .ata = [](const AyarDeger& d) { camSimYolGosterAta(d.b); }}); s.ayarKaydet({.kimlik = "cam.sim_takim_goster", .kategori = "CAM", .ad = "Simülasyonda takımı göster", .aciklama = "Kapalı: hareketli takım gövdesi 3B sahnede çizilmez. Yolla " "birlikte kapatılırsa sahnede yalnız oyulmuş kütük kalır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(camSimTakimGosterAl()); }, .ata = [](const AyarDeger& d) { camSimTakimGosterAta(d.b); }}); // ---- Malzeme / doku ---- s.ayarKaydet({.kimlik = "malzeme.doku_en_buyuk_kenar", .kategori = "Malzeme", .ad = "Doku çözünürlük tavanı (px)", .aciklama = "Yüklenen doku bu kenardan büyükse orantılı küçültülür. " "8K doku = ~256 MB VRAM; tavan VRAM'i korur. Yeni belgede " "geçerli olur (yüklü dokular etkilenmez).", .tip = AyarTip::F64, .varsayilan = dF(4096.0), .min = 256.0, .maks = 8192.0, .al = [] { return dF((f64)malzemeDokuTavanAl()); }, .ata = [](const AyarDeger& d) { malzemeDokuTavanAta((int)d.f); }}); s.ayarKaydet({.kimlik = "malzeme.anizotropi", .kategori = "Malzeme", .ad = "Anizotropik filtre", .aciklama = "Eğik yüzeylerde doku netliği (1 = kapalı, 16 = en net). " "GPU desteklemiyorsa yok sayılır.", .tip = AyarTip::F64, .varsayilan = dF(16.0), .min = 1.0, .maks = 16.0, .al = [] { return dF(malzemeAnizotropiAl()); }, .ata = [](const AyarDeger& d) { malzemeAnizotropiAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "cam.kutuk_batch_ms", .kategori = "CAM", .ad = "Kütük oyma bütçesi (ms/kare)", .aciklama = "Talaş kaldırma simülasyonunun kare başına CPU/GPU süresi. " "Büyük → oyma hızlı biter ama kare düşer; küçük → akıcı UI.", .tip = AyarTip::F64, .varsayilan = dF(5.0), .min = 1.0, .maks = 33.0, .al = [] { return dF(camSimKutukBatchMsAl()); }, .ata = [](const AyarDeger& d) { camSimKutukBatchMsAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "cam.kutuk_mesh_ms", .kategori = "CAM", .ad = "Kütük mesh yenileme aralığı (ms)", .aciklama = "Oyulan kütüğün görsel mesh'i en az bu aralıkla çıkarılır " "(eski davranış her kareydi → büyük kütükte kasıyordu).", .tip = AyarTip::F64, .varsayilan = dF(100.0), .min = 16.0, .maks = 1000.0, .al = [] { return dF(camSimKutukMeshMsAl()); }, .ata = [](const AyarDeger& d) { camSimKutukMeshMsAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "cam.sim_ses", .kategori = "CAM", .ad = "Simülasyon sesi (varsayılan)", .aciklama = "Oynatımda prosedürel işleme sesi (iğ whir'i + kesme " "gıcırtısı). Ses cihazı yoksa sessiz. Pencere içinden de açılır.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(camSimSesAl()); }, .ata = [](const AyarDeger& d) { camSimSesAta(d.b); }}); s.ayarKaydet({.kimlik = "cam.sim_kamera_takip", .kategori = "CAM", .ad = "Simülasyonda kamera takip (varsayılan)", .aciklama = "Kamera odağı hareketli takımı izler (orbit/zoom korunur).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(camSimKameraTakipAl()); }, .ata = [](const AyarDeger& d) { camSimKameraTakipAta(d.b); }}); s.ayarKaydet({.kimlik = "cam.kutuk_maks_hucre", .kategori = "CAM", .ad = "Kütük maks hücre (en uzun eksen)", .aciklama = "Talaş kaldırma grid'inde en uzun eksendeki hücre sayısı üst " "sınırı. ÖLÇÜLDÜ: sınırsızken 1mm çöz.+büyük stok → ~28M " "vertexli mesh → 1.34 GB GPU buffer → donma. Aşınca çözünürlük " "otomatik kabalaşır. Büyük = daha ince ama daha ağır (VRAM).", .tip = AyarTip::Int, .varsayilan = dInt(300), .min = 16, .maks = 2000, .al = [] { return dInt((i64)camSimKutukMaksHucreAl()); }, .ata = [](const AyarDeger& d) { camSimKutukMaksHucreAta((u32)d.i); }}); s.ayarKaydet({.kimlik = "cam.kutuk_async", .kategori = "CAM", .ad = "Async kütük carve (gerçek-zamanlı)", .aciklama = "Talaş kaldırma simülasyonu worker thread'inde koşar → oynatma " "ana thread'i bloklanmaz (akıcı 60 FPS, gerçek-zamanlı oyma). " "Kapalı = eski senkron yol (kare başına bütçeli). GPU kütük " "motorunda otomatik devre dışı (Vulkan gönderimi worker'da yasak).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(camSimKutukAsyncAl()); }, .ata = [](const AyarDeger& d) { camSimKutukAsyncAta(d.b); }}); s.ayarKaydet({.kimlik = "cam.kutuk_keskin", .kategori = "CAM", .ad = "Keskin kütük mesh (Dual Contouring)", .aciklama = "Talaş kaldırma mesh'inde keskin köşe/kenarı korur (Marching " "Cubes ~1 hücre yuvarlar). SDF gradyanı + QEF ile hücre köşesi " "keskin yere oturur. SDF+MC kipinde; cache'siz tam grid → daha " "yavaş güncelleme (kalite görünümü). Kapalı: MC (hızlı, yumuşak).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(camSimKutukKeskinAl()); }, .ata = [](const AyarDeger& d) { camSimKutukKeskinAta(d.b); }}); s.ayarKaydet({.kimlik = "cam.kutuk_takim_uzat", .kategori = "CAM", .ad = "Takımı stok üstüne uzat (kütük)", .aciklama = "Kesici boyu (ör. 50mm) dalış derinliğinden (ör. 363mm mold) " "kısaysa, tip'in üstünde kesilmemiş 'tavan' kalır → 2-yüzey / " "'oymuyor iterek gidiyor' görünümü. Açık: kesici katı stok " "üstüne kadar keser (görsel takım boyu değişmez). Kapalı: " "gerçek kesici boyu.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(camSimKutukTakimUzatAl()); }, .ata = [](const AyarDeger& d) { camSimKutukTakimUzatAta(d.b); }}); // ESKİ (geri uyum): kimlikler kalıcı dosyada olabilir → tanım silinmez, ama artık // yalnız okunur köprü. `ata` bilerek BOŞ: açılışta yüklenen eski değer merkezî // "pencere.grid_adim" ayarını EZMESİN. s.ayarKaydet({.kimlik = "cam.sim_grid_adim", .kategori = "CAM", .ad = "Simülasyon arka plan grid boyu (px) — ESKİ", .aciklama = "Artık merkezî: Ayarlar → Pencere → Izgara adımı. Bu satır " "yalnız geri uyum için durur; değeri değiştirmez.", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = 2.0, .maks = 40.0, .al = [] { return dF(ui::webSkinGridAdim()); }, .ata = [](const AyarDeger&) {}}); s.ayarKaydet({.kimlik = "kafa.grid_adim", .kategori = "CAM", .ad = "Açılı kafa penceresi grid boyu (px) — ESKİ", .aciklama = "Artık merkezî: Ayarlar → Pencere → Izgara adımı. Bu satır " "yalnız geri uyum için durur; değeri değiştirmez.", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = 2.0, .maks = 40.0, .al = [] { return dF(ui::webSkinGridAdim()); }, .ata = [](const AyarDeger&) {}}); s.ayarKaydet({.kimlik = "cam.sim_renk_esik", .kategori = "CAM", .ad = "Yol renk eşiği (segment)", .aciklama = "Bu segment sayısı üstünde takım yolu tek renk (cyan) çizilir. " "Renkli mod hareket türü başına ayrı düğüm + prefix tutar " "(N×16B bellek); vertex sayısı aynıdır. Tipik CATIA APT'si " "200k+ segment olduğundan varsayılan 1.000.000 — renkler " "korunur. Kurulum yavaşlarsa düşür (fikocad.log '[sim] kur' " "satırı gerçek süreyi verir).", .tip = AyarTip::Int, .varsayilan = dInt(1000000), .min = 0, .maks = 100000000, .al = [] { return dInt((i64)camSimRenkEsikAl()); }, .ata = [](const AyarDeger& d) { camSimRenkEsikAta((u32)d.i); }}); } void kaydetSketcher(AyarSistemi& s, UygulamaBaglam& b) { SketchUIDurum* sk = &b.sketch; parca::PartDesignSistemi* pd = &b.partD; s.ayarKaydet({.kimlik = "sketcher.feature_sonrasi_gizle", .kategori = "Sketcher", .ad = "Kullanılan sketch'i gizle", .aciklama = "Sketch bir feature (Pad/Cep/...) tarafından kullanılınca " "otomatik gizlenir (CATIA). Düzenlemek için açınca görünür. " "Kapalı: eski — sketch görünür kalır.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [pd] { return dBool(pd->sketchOtoGizle()); }, .ata = [pd](const AyarDeger& d) { pd->sketchOtoGizleAyarla(d.b); }}); s.ayarKaydet({.kimlik = "sketcher.oto_geo_kisit", .kategori = "Sketcher", .ad = "Otomatik geometrik kısıt", .aciklama = "Çizim sırasında coincidence/yatay/dikey kısıtları otomatik ekle.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [sk] { return dBool(sk->sketchOtoGeoKisit); }, .ata = [sk](const AyarDeger& d) { sk->sketchOtoGeoKisit = d.b; }}); s.ayarKaydet({.kimlik = "sketcher.oto_olcu_kisit", .kategori = "Sketcher", .ad = "Otomatik boyutsal kısıt", .aciklama = "Canlı giriş değerlerinden ölçü kısıtı üret.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [sk] { return dBool(sk->sketchOtoOlcuKisit); }, .ata = [sk](const AyarDeger& d) { sk->sketchOtoOlcuKisit = d.b; }}); s.ayarKaydet({.kimlik = "sketcher.poly_kenar", .kategori = "Sketcher", .ad = "Çokgen kenar sayısı", .aciklama = "Çokgen aracının varsayılan kenar adedi.", .tip = AyarTip::Int, .varsayilan = dInt(6), .min = 3, .maks = 20, .al = [sk] { return dInt(sk->sketchPolyKenar); }, .ata = [sk](const AyarDeger& d) { sk->sketchPolyKenar = (int)d.i; }}); s.ayarKaydet({.kimlik = "sketcher.oto_cakisik_tol", .kategori = "Sketcher", .ad = "Oto çakışık toleransı", .aciklama = "İki uç noktası bu mesafeden yakınsa otomatik coincidence kısıtı " "eklenir (sketch birimi). Büyük = kolay yakalar ama fazla kısıt üretir.", .tip = AyarTip::F64, .varsayilan = dF(0.15), .min = 0.001, .maks = 2, .al = [sk] { return dF(sk->sketchOtoCakisikTol); }, .ata = [sk](const AyarDeger& d) { sk->sketchOtoCakisikTol = d.f; }}); s.ayarKaydet({.kimlik = "sketcher.tam_kisit_renk", .kategori = "Sketcher", .ad = "Tam kısıtlı eleman yeşil", .aciklama = "Eskiz az-kısıtlıyken bile yeri kilitlenmiş elemanlar yeşil " "çizilir (CATIA). Kapalı: eski — renk yalnız eskiz genel " "durumuna göre.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [sk] { return dBool(sk->sketchTamKisitRenk); }, .ata = [sk](const AyarDeger& d) { sk->sketchTamKisitRenk = d.b; }}); s.ayarKaydet({.kimlik = "sketcher.oto_cakisik_yay_uc", .kategori = "Sketcher", .ad = "Oto çakışık: yay/spline uçları", .aciklama = "Yay ve spline uçları da otomatik coincidence kısıtına girer " "(CATIA davranışı). Kapalı: eski — yalnız çizgi uçları.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [sk] { return dBool(sk->sketchOtoCakisikYayUc); }, .ata = [sk](const AyarDeger& d) { sk->sketchOtoCakisikYayUc = d.b; }}); s.ayarKaydet({.kimlik = "sketcher.oto_hv_esik", .kategori = "Sketcher", .ad = "Oto yatay/dikey eşiği", .aciklama = "Çizgi bu sin-sapmadan düzse otomatik Yatay/Dikey kısıtı eklenir " "(0.035 ≈ 2°). Büyük = daha eğik çizgileri de düzler.", .tip = AyarTip::F64, .varsayilan = dF(0.035), .min = 0.001, .maks = 0.3, .al = [sk] { return dF(sk->sketchOtoHVEsik); }, .ata = [sk](const AyarDeger& d) { sk->sketchOtoHVEsik = d.f; }}); s.ayarKaydet({.kimlik = "sketcher.oto_min_uzunluk", .kategori = "Sketcher", .ad = "Oto H/V asgari uzunluk", .aciklama = "Bu uzunluktan kısa çizgilere otomatik Yatay/Dikey kısıtı " "eklenmez (kararsız yön → sketch birimi).", .tip = AyarTip::F64, .varsayilan = dF(0.5), .min = 0.01, .maks = 10, .al = [sk] { return dF(sk->sketchOtoMinUzunluk); }, .ata = [sk](const AyarDeger& d) { sk->sketchOtoMinUzunluk = d.f; }}); s.ayarKaydet({.kimlik = "sketcher.fillet_yedek_yari", .kategori = "Sketcher", .ad = "İnteraktif fillet yedek yarıçapı", .aciklama = "İnteraktif köşe yuvarlat/pah aracında değer kutusu boş ve imleçten " "geçerli boyut türetilemezse kullanılan yedek yarıçap/mesafe.", .tip = AyarTip::F64, .varsayilan = dF(1.0), .min = 0.01, .maks = 100, .al = [sk] { return dF(sk->sketchFilletYedekYari); }, .ata = [sk](const AyarDeger& d) { sk->sketchFilletYedekYari = d.f; }}); } void kaydetGorunum(AyarSistemi& s, UygulamaBaglam& b, Cekirdek* c) { std::vector temalar; for (int i = 0; i < ui::temaSayisi(); ++i) temalar.push_back(ui::temaAl(i).ad); s.ayarKaydet({.kimlik = TEMA_KIMLIK, .kategori = "Görünüm", .ad = "Tema", .aciklama = "FikoUi tema seçimi (tüm pencereler anında değişir).", .tip = AyarTip::Secenek, .varsayilan = dMetin("Koyu"), .secenekler = std::move(temalar), .al = [] { return dMetin(ui::tema().ad); }, .ata = [c](const AyarDeger& d) { if (ui::temaSec(d.metin.c_str())) c->olaylar().yayinla(TemaDegisti{}, ui::tema().ad); }}); s.ayarKaydet({.kimlik = "gorunum.yogunluk", .kategori = "Görünüm", .ad = "Arayüz yoğunluğu", .aciklama = "Pencere padding/aralık ölçeği: Kompakt (ekranda daha fazla " "alan) · Normal · Ferah. Tüm pencerelere anında yansır.", .tip = AyarTip::Secenek, .varsayilan = dMetin("Normal"), .secenekler = {"Kompakt", "Normal", "Ferah"}, .al = [] { const float y = ui::yogunluk(); return dMetin(y < 0.93f ? "Kompakt" : (y > 1.1f ? "Ferah" : "Normal")); }, .ata = [](const AyarDeger& d) { float f = 1.0f; if (d.metin == "Kompakt") f = 0.85f; else if (d.metin == "Ferah") f = 1.2f; ui::yogunlukAyarla(f); }}); bool* hb = &b.hoverBilgiAcik; s.ayarKaydet({.kimlik = "gorunum.hoverBilgi", .kategori = "Görünüm", .ad = "Hover bilgi kartı", .aciklama = "İmleç altındaki yüz/kenar/nokta/gövde B-Rep bilgi kartını göster.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [hb] { return dBool(*hb); }, .ata = [hb](const AyarDeger& d) { *hb = d.b; }}); int* hg = &hoverGecikmeMs(); s.ayarKaydet({.kimlik = "gorunum.hoverGecikme", .kategori = "Görünüm", .ad = "Hover kartı gecikmesi (ms)", .aciklama = "İmleç bir öğe üzerinde bu süre beklerse bilgi kartı belirir. " "İmleç başka öğeye kayınca sayaç sıfırlanır (0 = anında).", .tip = AyarTip::Int, .varsayilan = dInt(500), .min = 0, .maks = 2000, .al = [hg] { return dInt(*hg); }, .ata = [hg](const AyarDeger& d) { *hg = (int)d.i; }}); UygulamaBaglam* ub = &b; s.ayarKaydet({.kimlik = "gorunum.kalite_ince", .kategori = "Görünüm", .ad = "3D gösterim kalitesi (%)", .aciklama = "Eğri/yüzey tessellation yoğunluğu: %0 = Düşük (hızlı önizleme), " "%100 = Ultra (pürüzsüz eğri). Yalnız görsel; B-Rep değişmez.", .tip = AyarTip::F64, .varsayilan = dF(geometri::kaliteFaktor() * 100.0), .min = 0, .maks = 100, .al = [] { return dF(geometri::kaliteFaktor() * 100.0); }, .ata = [ub](const AyarDeger& d) { geometri::kaliteFaktorAta(d.f / 100.0); for (auto& dg : ub->sahne.dugumler()) dg.yenidenInsaGerek = true; }}); s.ayarKaydet({.kimlik = "gorunum.orbit_lod_sapma", .kategori = "Görünüm", .ad = "Orbit LOD kabalığı", .aciklama = "Döndürme/gezinme sırasında geçici KABA mesh sapması. Büyük = daha az " "üçgen (rough modelde akıcı orbit) ama köşeli; küçük = pürüzsüz ama " "yavaş. Fare durunca tam kalite döner. Yalnız görsel; B-Rep değişmez.", .tip = AyarTip::F64, .varsayilan = dF(geometri::kabaLodSapma()), .min = 0.006, .maks = 0.05, .al = [] { return dF(geometri::kabaLodSapma()); }, .ata = [ub](const AyarDeger& d) { geometri::kabaLodSapmaAta(d.f); for (auto& dg : ub->sahne.dugumler()) dg.yenidenInsaGerek = true; }}); s.ayarKaydet({.kimlik = "geometri.usd_yuz_esigi", .kategori = "Görünüm", .ad = "Yüzey birleştirme eşiği (yüz)", .aciklama = "İt/çek sonrası koplanar yüzleri birleştirme yalnız yüz sayısı bu " "eşiğin ALTINDAYKEN çalışır. Eşik üstünde uzatılan yüzey komşusuyla " "birleşmez (yama görünümü; geometri doğru). Birleştirme artık arka " "planda koşar ve değişmeyen yüzlerin üçgenlemesi korunur — eşiği " "düşürmek yalnız aşırı devasa modellerde gerekebilir.", .tip = AyarTip::F64, .varsayilan = dF((f64)geometri::usdYuzEsigi()), .min = 100, .maks = 1000000, .al = [] { return dF((f64)geometri::usdYuzEsigi()); }, .ata = [](const AyarDeger& d) { geometri::usdYuzEsigiAta((u32)d.f); }}); s.ayarKaydet({.kimlik = "geometri.fillet_deneme_sure", .kategori = "Görünüm", .ad = "Fillet deneme süresi (ms)", .aciklama = "Fillet/pah köşe-clamp yeniden denemeleri için zaman kutusu: tek " "deneme bu süreyi aşıp başarısız olursa kalan küçültme denemeleri " "atlanır (devasa gövdede başarısız fillet dakikalarca sürmesin). " "Küçük gövdede davranış değişmez (6 kademeli clamp).", .tip = AyarTip::F64, .varsayilan = dF(geometri::filletDenemeMs()), .min = 250, .maks = 60000, .al = [] { return dF(geometri::filletDenemeMs()); }, .ata = [](const AyarDeger& d) { geometri::filletDenemeMsAta(d.f); }}); s.ayarKaydet({.kimlik = "gorunum.kaba_async", .kategori = "Görünüm", .ad = "Kaba LOD arka planda", .aciklama = "Orbit/hover kaba mesh'ini arka planda üretir → feature işlemleri ve " "import devasa modelde bloklanmaz (kaba hazır olana dek ince mesh " "çizilir). Kapalıyken eski davranış: işlem içinde senkron üretim.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(kabaMeshArkaplan()); }, .ata = [](const AyarDeger& d) { kabaMeshArkaplan() = d.b; }}); s.ayarKaydet({.kimlik = "import.paralel_mesh", .kategori = "Görünüm", .ad = "Import paralel üçgenleme", .aciklama = "STEP/IGES ilk açılışında üçgenlemeyi (BRepMesh) tüm çekirdeklerde " "paralel yapar → ölçüldü 5×'e varan hız (dev model mesh 138ms→26ms). " "Yalnız taze import gövdesi worker'da mesh'lenirken güvenlidir; " "boolean/feature sonrası mesh bu yolu kullanmaz. Sorun olursa kapatın.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(importParalelMesh()); }, .ata = [](const AyarDeger& d) { importParalelMesh() = d.b; }}); s.ayarKaydet({.kimlik = "gorunum.sapma_kuantala", .kategori = "Görünüm", .ad = "Mesh sapması kademeleme", .aciklama = "Mesh yoğunluğunu sabit kademelere yuvarlar → fillet/it-çek gibi " "işlemlerden sonra yalnız DEĞİŞEN yüzler yeniden üçgenlenir (devasa " "modelde işlem hızının kökü). Kapatılırsa her işlem tüm gövdeyi " "yeniden üçgenleyebilir. Yalnız görsel; B-Rep değişmez.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(geometri::sapmaKuantala()); }, .ata = [](const AyarDeger& d) { geometri::sapmaKuantalaAta(d.b); }}); s.ayarKaydet({.kimlik = "gorunum.orbit_lod_gecikme", .kategori = "Görünüm", .ad = "Orbit LOD gecikmesi (kare)", .aciklama = "Fare durduktan sonra kaç kare KABA mesh'te kalınıp tam kaliteye " "dönüleceği (~kare/60 = saniye; 8 ≈ 130ms). Büyük = daha akıcı hisseder " "ama geç netleşir; küçük = çabuk netleşir. Yalnız görsel LOD zamanlaması.", .tip = AyarTip::Int, .varsayilan = dInt(8), .min = 2, .maks = 30, .al = [] { return dInt(orbitLodGecikmeKare()); }, .ata = [](const AyarDeger& d) { orbitLodGecikmeKare() = (int)d.i; }}); s.ayarKaydet({.kimlik = "gorunum.bireysel_orbit_lod", .kategori = "Görünüm", .ad = "Bireysel çizimde orbit LOD", .aciklama = "Az gövdeli sahnede (mega-parti eşiği altı — dev tek-gövde modeller) " "döndürme/gezinme sırasında geçici KABA mesh çizilir → çok yüksek " "vertexli modelde akıcı orbit/hover. Fare durunca tam kalite döner. " "Yalnız görsel; B-Rep ve seçim değişmez.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(bireyselOrbitLod()); }, .ata = [](const AyarDeger& d) { bireyselOrbitLod() = d.b; }}); s.ayarKaydet({.kimlik = "gorunum.etkilesim_lod_aktif", .kategori = "Görünüm", .ad = "Etkileşim LOD (kalite düşürme)", .aciklama = "Döndürme/gezinme sırasında yüzey kalitesinin geçici düşürülmesi (kaba " "mesh). AÇIK = ağır modelde akıcı orbit, fare durunca tam kalite döner. " "KAPALI = her zaman tam kalite, kaliteye hiç dokunulmaz (mesh titremesi " "tamamen kalkar; çok ağır modelde orbit yavaşlayabilir). Yalnız görsel.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(etkilesimLodAktif()); }, .ata = [](const AyarDeger& d) { etkilesimLodAktif() = d.b; }}); s.ayarKaydet({.kimlik = "gorunum.lod_hover_tetik", .kategori = "Görünüm", .ad = "Fare gezerken de kalite düşür", .aciklama = "KAPALI (varsayılan) = fareyi boşta gezdirmek yüzey kalitesini " "DÜŞÜRMEZ; kaba mesh yalnız gerçek navigasyonda (aşağıdaki döndür/pan/" "zoom anahtarları) devreye girer → boşta gezerken kalite inip çıkmaz. " "AÇIK = eski davranış (hover da tetikler). Yalnız görsel; B-Rep değişmez.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(lodHoverTetik()); }, .ata = [](const AyarDeger& d) { lodHoverTetik() = d.b; }}); s.ayarKaydet({.kimlik = "gorunum.lod_dondur", .kategori = "Görünüm", .ad = "Döndürmede kalite düşür", .aciklama = "Modeli döndürürken (orbit) geçici kaba mesh çiz → ağır modelde akıcı " "döndürme, bırakınca tam kalite döner. Kapalı = döndürürken de tam kalite.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(lodDondurAktif()); }, .ata = [](const AyarDeger& d) { lodDondurAktif() = d.b; }}); s.ayarKaydet({.kimlik = "gorunum.lod_pan", .kategori = "Görünüm", .ad = "Taşımada kalite düşür", .aciklama = "Görünümü taşırken (pan) geçici kaba mesh çiz. Kapalı = taşırken de " "tam kalite.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(lodPanAktif()); }, .ata = [](const AyarDeger& d) { lodPanAktif() = d.b; }}); s.ayarKaydet({.kimlik = "gorunum.lod_zoom", .kategori = "Görünüm", .ad = "Zoomda kalite düşür", .aciklama = "Yakınlaştırırken (sürükle veya fare tekerleği) geçici kaba mesh çiz. " "Kapalı = zoom sırasında da tam kalite.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(lodZoomAktif()); }, .ata = [](const AyarDeger& d) { lodZoomAktif() = d.b; }}); s.ayarKaydet({.kimlik = "gorunum.bireysel_lod_min_indeks", .kategori = "Görünüm", .ad = "Bireysel LOD alt eşiği (indeks)", .aciklama = "Bireysel çizim yolunda etkileşim LOD'unun devreye gireceği en küçük " "gövde indeks sayısı. Altındaki (küçük/orta) modelde kaba mesh'e hiç " "geçilmez → fare gezerken görsel titreşim olmaz; ince mesh zaten ucuz. " "150000 indeks = 50000 üçgen.", .tip = AyarTip::Int, .varsayilan = dInt(150'000), .min = 0, .maks = 10'000'000, .al = [] { return dInt(bireyselLodMinIndeks()); }, .ata = [](const AyarDeger& d) { bireyselLodMinIndeks() = (int)d.i; }}); s.ayarKaydet({.kimlik = "gorunum.cok_secim_vurgu_esigi", .kategori = "Görünüm", .ad = "Çok-seçim vurgu eşiği", .aciklama = "Bundan FAZLA gövde seçiliyse (ör. ürün ağacından büyük grup) seçili " "gövdeler mega-partide kalır → seçim değişiminde yeniden-pişirme (cook) ve " "binlerce bireysel/overlay draw OLMAZ. Karşılığı: eşik üstünde 3B per-gövde " "vurgu atlanır (ürün ağacı seçimi zaten gösterir). 0 = kapalı (eski " "davranış: her seçili ayrı çizilir+vurgulanır, her seçimde cook).", .tip = AyarTip::Int, .varsayilan = dInt(3000), .min = 0, .maks = 100'000, .al = [] { return dInt(cokSecimVurguEsigi()); }, .ata = [](const AyarDeger& d) { cokSecimVurguEsigi() = (int)d.i; }}); s.ayarKaydet({.kimlik = "gorunum.secim_cook_atla", .kategori = "Görünüm", .ad = "Seçimde yeniden-pişirmeyi atla", .aciklama = "Seçili gövdeyi mega-partiden çıkarmaz (hover gibi partide tutar) → HER " "seçim değişiminde mega-parti yeniden pişmez (~18ms hitch gider, küçük " "seçimde bile). Vurgu, partinin üstüne z-bias'lı overlay ile basılır. " "KAPALI = eski davranış (seçili bireysel çizilir + her seçimde pişirme). " "Açtıktan sonra seçili yüzde titreme/speckle olmadığını kontrol edin.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(secimCookAtla()); }, .ata = [](const AyarDeger& d) { secimCookAtla() = d.b; }}); s.ayarKaydet({.kimlik = "secim.yuz_aralik_ciz", .kategori = "Görünüm", .ad = "Vurguda yalnız seçili yüzü çiz", .aciklama = "Seçim/hover vurgusu için gövdenin TÜM mesh'ini yeniden çizmek yerine " "yalnız o yüzün indeks aralığı çizilir (kalan üçgenleri shader zaten " "atıyordu). Ölçüm: 481k üçgenli gövdede tek yüz seçiliyken 25 FPS / " "24 ms GPU. Mesh üçgenleri yüze göre bitişik değilse otomatik olarak " "tam çizime düşer. KAPALI = eski davranış.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(yuzAralikCiz()); }, .ata = [](const AyarDeger& d) { yuzAralikCiz() = d.b; }}); s.ayarKaydet({.kimlik = "secim.cpu_kenar_pick", .kategori = "Görünüm", .ad = "Kenar hover CPU pick", .aciklama = "Kenar hover'ını ekran-uzayı CPU testine taşır (yüz pick'i gibi) → GPU " "pick'te 'her hover'da TÜM kenarları çiz' yükü kalkar (kenar-yoğun/dev " "modelde asıl kenar gecikmesi buydu). Datum kenarları yine GPU'da (az). " "KAPALI = eski GPU kenar pass'ı. ~6px yakalama toleransı.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(cpuKenarPick()); }, .ata = [](const AyarDeger& d) { cpuKenarPick() = d.b; }}); s.ayarKaydet({.kimlik = "render.zaman_asimi_tolerans", .kategori = "Görünüm", .ad = "GPU kare gecikme toleransı", .aciklama = "GPU bir kareyi 2 sn içinde bitiremezse ART ARDA kaç kez tolere " "edilsin (kare atlanır, uygulama yaşar). Aşılırsa aygıt kayıp " "sayılır ve temiz kapanışa geçilir. 0 = eski davranış (ilk " "gecikmede kapanış). Hızlı pencere boyutlandırmada tek bir " "gecikme uygulamayı donduruyordu (ölçüldü 07-21).", .tip = AyarTip::Int, .varsayilan = dInt(3), .min = 0, .maks = 30, .al = [] { return dInt((i64)VulkanAygit::zamanAsimiTolerans()); }, .ata = [](const AyarDeger& d) { VulkanAygit::zamanAsimiTolerans() = (int)d.i; }}); static const char* msaaAd[4] = {"Kapalı", "2x", "4x", "8x"}; static const int msaaOrnek[4] = {1, 2, 4, 8}; // Ayarlar penceresi CANLI msaaOrnekSayisi()'yi göstermez (o kuruluşta sabitlendi, // burada değiştirilemez) — "seçilen ama henüz uygulanmamış" değeri ayrıca tutulur. // Açılışta canlı değerle eşit başlar; yalnız bu ayarın ata'sı üzerinden değişir. static int g_msaaSecili = (int)VulkanAygit::msaaOrnekSayisi(); s.ayarKaydet({.kimlik = "render.msaa_ornek", .kategori = "Görünüm", .ad = "Anti-alias (MSAA)", .aciklama = "3B viewport kenar/yüzey pürüzsüzleştirme (çok-örnekli " "anti-aliasing). Cihazın desteklemediği değer otomatik en " "yakın desteklenene düşer. Render pass + tüm sahne " "pipeline'ları kurulum anında bu değere bakar → değişiklik " "YALNIZ YENİDEN BAŞLATMADA etkir.", .tip = AyarTip::Secenek, .varsayilan = dMetin(msaaAd[2]), // 4x .secenekler = {msaaAd[0], msaaAd[1], msaaAd[2], msaaAd[3]}, .al = [] { for (int i = 0; i < 4; ++i) if (msaaOrnek[i] == g_msaaSecili) return dMetin(msaaAd[i]); return dMetin(msaaAd[2]); }, .ata = [](const AyarDeger& d) { // Kurulum anında sabitlenmiş → canlı örnek sayısını DEĞİŞTİRMEYİZ // (render pass zaten kurulu). Yalnız "seçili" değeri güncelle // (pencere doğru gösterir) — kalıcı yazma degisti köprüsünde olur, // gerçek etki bir sonraki açılışta main.cpp'nin erken okumasıyla gelir. for (int i = 0; i < 4; ++i) if (d.metin == msaaAd[i]) { g_msaaSecili = msaaOrnek[i]; return; } }}); s.ayarKaydet({.kimlik = "render.takas_kurma_aralik_ms", .kategori = "Görünüm", .ad = "Pencere boyutlandırma yeniden-kurma aralığı (ms)", .aciklama = "Pencere sürüklenirken görüntü zinciri (swapchain) en fazla bu " "aralıkla yeniden kurulur; aradaki kareler atlanır. Her WM_SIZE'da " "kurmak sürücüde aygıt kaybına yol açıyordu (ölçüldü 07-21). " "0 = eski davranış (her istekte anında kur).", .tip = AyarTip::Int, .varsayilan = dInt(60), .min = 0, .maks = 500, .al = [] { return dInt((i64)PencereYuzeyi::kurmaAralikMs()); }, .ata = [](const AyarDeger& d) { PencereYuzeyi::kurmaAralikMs() = (int)d.i; }}); s.ayarKaydet({.kimlik = "render.hedef_kararlilik_ms", .kategori = "Görünüm", .ad = "Offscreen hedef kararlılık süresi (ms)", .aciklama = "Görünüm/seçim hedefleri, istenen boyut bu kadar ms sabit " "kalmadıkça yeniden kurulmaz (pencere sürüklerken tahsis " "fırtınası önlenir). 0 = eski davranış. ÖLÇÜLDÜ 07-21: 0'da " "6 koşumun 5'i aygıt kaybıyla öldü, 250 ms'de 6/6 sağlam.", .tip = AyarTip::Int, .varsayilan = dInt(250), .min = 0, .maks = 1000, .al = [] { return dInt((i64)PencereYuzeyi::hedefKararlilikMs()); }, .ata = [](const AyarDeger& d) { PencereYuzeyi::hedefKararlilikMs() = (int)d.i; }}); s.ayarKaydet({.kimlik = "render.surukle_ciz", .kategori = "Görünüm", .ad = "Sürüklerken her boyut mesajında çiz", .aciklama = "AÇIK (eski davranış): pencere sürüklenirken her WM_SIZE'da " "anında bir kare çizilir. Bu kare sunum motorunu bekleyip " "1–2 sn takılabiliyor ve pencereyi donduruyor (ölçüldü 07-21). " "KAPALI: sürükleme sırasında çizim yalnız modal timer'dan gelir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(surukleCiz()); }, .ata = [](const AyarDeger& d) { surukleCiz() = d.b; }}); s.ayarKaydet({.kimlik = "render.sunum_kipi", .kategori = "Görünüm", .ad = "Sunum kipi (0=VSync · 1=Mailbox · 2=Anında)", .aciklama = "VSync (FIFO) GPU'yu ekran hızına sabitler. Mailbox/Anında " "gecikmeyi düşürür ama GPU'yu daha çok çalıştırır. " "Desteklenmeyen kip sessizce VSync'e döner. Değişiklik bir " "sonraki pencere boyutlandırmasında etkir.", .tip = AyarTip::Int, .varsayilan = dInt(0), .min = 0, .maks = 2, .al = [] { return dInt((i64)PencereYuzeyi::sunumKipi()); }, .ata = [](const AyarDeger& d) { PencereYuzeyi::sunumKipi() = (int)d.i; }}); s.ayarKaydet({.kimlik = "render.gozcu_saniye", .kategori = "Görünüm", .ad = "Donma gözcüsü eşiği (sn)", .aciklama = "Ana döngü bu kadar saniyedir kare tamamlamadıysa donma teşhisi " "loga yazılır (takıldığı adım). 0 = kapalı. Teşhis amaçlıdır, " "uygulamayı sonlandırmaz.", .tip = AyarTip::Int, .varsayilan = dInt(5), .min = 0, .maks = 120, .al = [] { return dInt((i64)gozcuSaniye()); }, .ata = [](const AyarDeger& d) { gozcuSaniye() = (int)d.i; }}); s.ayarKaydet({.kimlik = "render.aygit_kaybinda_yeniden_baslat", .kategori = "Görünüm", .ad = "GPU kaybında uygulamayı yeniden başlat", .aciklama = "GPU aygıtı kaybolduğunda uygulama kapanır ve kendini yeniden " "açar; oturum kurtarma belgeyi geri getirir. KAPALI = yalnız " "kapanır (elle yeniden açmak gerekir).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(aygitKaybindaYenidenBaslat()); }, .ata = [](const AyarDeger& d) { aygitKaybindaYenidenBaslat() = d.b; }}); s.ayarKaydet({.kimlik = "kinematik.halka_oto_coz", .kategori = "Görünüm", .ad = "Kapalı zinciri otomatik çöz", .aciklama = "Mekanizma uygulanırken kapalı zincir (4-çubuk gibi halkalı) " "varsa bağımlı mafsallar otomatik çözülür. KAPALI = ham ileri " "kinematik yazılır ve halka AÇIK kalır (geometri kopuk görünür). " "Ağaç mekanizmada etkisizdir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(kinematik::halkaOtoCoz()); }, .ata = [](const AyarDeger& d) { kinematik::halkaOtoCoz() = d.b; }}); s.ayarKaydet({.kimlik = "kinematik.girisim_asgari_hacim", .kategori = "Görünüm", .ad = "Girişim asgari hacmi (mm³)", .aciklama = "DMU çarpışma taramasında kesin B-Rep kesişiminin hacmi bu " "değerin altındaysa yalnız teğet temas sayılır: raporlanmaz ve " "sahnede işaretlenmez.", .tip = AyarTip::F64, .varsayilan = dF(1e-9), .al = [] { return dF(kinematik::girisimAsgariHacim()); }, .ata = [](const AyarDeger& d) { kinematik::girisimAsgariHacim() = d.f; }}); s.ayarKaydet({.kimlik = "kinematik.girisim_renk", .kategori = "Görünüm", .ad = "Girişim gövdesi rengi", .aciklama = "Çarpışma taraması sahneye işaretlendiğinde oluşturulan girişim " "hacminin rengi.", .tip = AyarTip::Renk, .varsayilan = dRenk({0.95f, 0.15f, 0.10f}), .al = [] { return dRenk(kinematik::girisimRenk()); }, .ata = [](const AyarDeger& d) { kinematik::girisimRenk() = d.renk; }}); s.ayarKaydet({.kimlik = "kinematik.girisim_alfa", .kategori = "Görünüm", .ad = "Girişim gövdesi saydamlığı", .aciklama = "1 = opak. Yarı saydam bırakılırsa girişimin ALTINDAKİ parçalar " "görünür kalır.", .tip = AyarTip::F32, .varsayilan = dF(0.55), .al = [] { return dF((f64)kinematik::girisimAlfa()); }, .ata = [](const AyarDeger& d) { kinematik::girisimAlfa() = (f32)d.f; }}); s.ayarKaydet({.kimlik = "cae.fem_en_fazla_adim", .kategori = "Görünüm", .ad = "FEM çözücü iterasyon üst sınırı", .aciklama = "Lineer statik FEM (hex8) ön-koşullu CG adım tavanı. Büyük " "modelde yetmezse sonuç 'yakınsamadı' işaretlenir — sessizce " "yanlış sonuç dönmez.", .tip = AyarTip::Int, .varsayilan = dInt(5000), .al = [] { return dInt(cae::femEnFazlaAdim()); }, .ata = [](const AyarDeger& d) { cae::femEnFazlaAdim() = (int)d.i; }}); s.ayarKaydet({.kimlik = "cae.fem_tolerans", .kategori = "Görünüm", .ad = "FEM bağıl artık toleransı", .aciklama = "CG durma ölçütü: ‖r‖/‖f‖ bu değerin altına inince çözüm " "yakınsamış sayılır.", .tip = AyarTip::F64, .varsayilan = dF(1e-8), .al = [] { return dF(cae::femTolerans()); }, .ata = [](const AyarDeger& d) { cae::femTolerans() = d.f; }}); s.ayarKaydet({.kimlik = "cae.asgari_cidar_hucre", .kategori = "Görünüm", .ad = "FEM asgari cidar hücresi", .aciklama = "Bir kesitte en az bu kadar eleman olmalı; altındaysa kaba " "kafes uyarısı verilir (1–2 hücrelik duvar eğilmeyi temsil " "edemez, sonuç sessizce anlamsız çıkar).", .tip = AyarTip::Int, .varsayilan = dInt(4), .min = 1, .maks = 20, .al = [] { return dInt((i64)cae::asgariCidarHucre()); }, .ata = [](const AyarDeger& d) { cae::asgariCidarHucre() = (u32)d.i; }}); s.ayarKaydet({.kimlik = "cae.konservatif_kafes", .kategori = "Görünüm", .ad = "FEM kafesinde ince cidarı koru", .aciklama = "AÇIK: hücre kutusu yüzeyi kesiyorsa da malzeme sayılır. " "KAPALI (merkez tabanlı) sınıflamada hücre boyundan ince cidar " "kafeste TAMAMEN kaybolur — ölçüldü: 2 mm plaka kaba kafeste " "sıfır hücre. Kapatmak yalnız hız içindir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(cae::konservatifKafes()); }, .ata = [](const AyarDeger& d) { cae::konservatifKafes() = d.b; }}); s.ayarKaydet({.kimlik = "dokum.voxel_sinifla_paralel", .kategori = "Görünüm", .ad = "Voxel sınıflamayı paralel koştur", .aciklama = "İç/dış ışın-parity taraması hücre başına bağımsızdır; paralel " "yol BİT-BİT aynı sonucu verir, yalnız hızlanır (ölçüldü: 110k " "hücrede 926 ms → 60 ms). Kapatmak yalnız teşhis içindir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(dokum::voxelSiniflaParalel()); }, .ata = [](const AyarDeger& d) { dokum::voxelSiniflaParalel() = d.b; }}); s.ayarKaydet({.kimlik = "dokum.voxel_paralel_esik", .kategori = "Görünüm", .ad = "Voxel paralel eşiği (hücre)", .aciklama = "Bu hücre sayısının altında iş parçacığı kurulumu kazançtan " "pahalıdır; küçük kafesler tek iş parçacığında koşar.", .tip = AyarTip::Int, .varsayilan = dInt(4096), .al = [] { return dInt(dokum::voxelParalelEsik()); }, .ata = [](const AyarDeger& d) { dokum::voxelParalelEsik() = (u32)d.i; }}); s.ayarKaydet({.kimlik = "cae.fem_paralel", .kategori = "Görünüm", .ad = "FEM matris çarpımını paralel koştur", .aciklama = "8-renkli şema (aynı renkteki hücreler düğüm paylaşmaz). " "ÖLÇÜLDÜ 07-21: kazandırmadı — 2560 hücrede 129→206 ms, 8640 " "hücrede 651→565 ms; bariyer maliyeti her matvec'te ödeniyor. " "Bu yüzden varsayılan KAPALI; kalıcı iş parçacığı havuzu " "yazıldığında yeniden ölçülecek.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(cae::femParalel()); }, .ata = [](const AyarDeger& d) { cae::femParalel() = d.b; }}); s.ayarKaydet({.kimlik = "cae.fem_paralel_esik", .kategori = "Görünüm", .ad = "FEM paralel eşiği (hücre)", .aciklama = "Bu hücre sayısının altında çözüm her hâlükârda seri koşar.", .tip = AyarTip::Int, .varsayilan = dInt(2000), .al = [] { return dInt(cae::femParalelEsik()); }, .ata = [](const AyarDeger& d) { cae::femParalelEsik() = (u32)d.i; }}); s.ayarKaydet({.kimlik = "cae.fem_blok_onkosul", .kategori = "Görünüm", .ad = "FEM'de 3×3 blok ön-koşullayıcı", .aciklama = "Düğüm başına 3×3 blok Jacobi (skaler köşegen yerine). ÖLÇÜLDÜ " "07-21: iterasyonu yalnız %2 düşürdü, süre kazancı gürültü " "içinde; düğüm başına 9 f64 fazladan bellek ister. Çözüm " "değişmez (fark ~1e-12). Varsayılan KAPALI.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(cae::femBlokOnkosul()); }, .ata = [](const AyarDeger& d) { cae::femBlokOnkosul() = d.b; }}); s.ayarKaydet({.kimlik = "gorunum.tampon_toplu_yukleme", .kategori = "Performans", .ad = "Düğüm tamponlarını toplu yükle", .aciklama = "AÇIK: bir düğümün vertex/indeks/kenar/nokta tamponları TEK " "komut tamponunda gönderilir (tek submit + tek fence). KAPALI " "(eski yol): her tampon ayrı anlık transfer — ÖLÇÜLDÜ 07-21: her " "transfer grafik kuyruğunda uçuştaki karenin arkasına girip ~60 ms " "bekliyor, düğüm başına ~1 sn ediyordu (25 ekleme ort. 1979 ms → " "57 ms).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(tamponTopluYukleme()); }, .ata = [](const AyarDeger& d) { tamponTopluYukleme() = d.b; }}); } void kaydetArayuz(AyarSistemi& s) { s.ayarKaydet({.kimlik = "arayuz.font_olcek", .kategori = "Arayüz", .ad = "Yazı boyutu", .aciklama = "Tüm panel/pencere yazı boyutu çarpanı (0.6 küçük – 1.8 büyük).", .tip = AyarTip::F64, .varsayilan = dF(1.0), .min = 0.6, .maks = 1.8, .al = [] { return dF(fikoUiAyar().fontOlcek); }, .ata = [](const AyarDeger& d) { fikoUiAyar().fontOlcek = (f32)d.f; }}); s.ayarKaydet({.kimlik = "arayuz.bosluk_x", .kategori = "Arayüz", .ad = "Yatay boşluk", .aciklama = "Öğeler arası yatay boşluk + çerçeve iç boşluğu (px).", .tip = AyarTip::F64, .varsayilan = dF(8.0), .min = 2.0, .maks = 20.0, .al = [] { return dF(fikoUiAyar().boslukX); }, .ata = [](const AyarDeger& d) { fikoUiAyar().boslukX = (f32)d.f; }}); s.ayarKaydet({.kimlik = "arayuz.bosluk_y", .kategori = "Arayüz", .ad = "Dikey boşluk", .aciklama = "Öğeler arası dikey boşluk (px). Satır aralığını belirler.", .tip = AyarTip::F64, .varsayilan = dF(4.0), .min = 1.0, .maks = 16.0, .al = [] { return dF(fikoUiAyar().boslukY); }, .ata = [](const AyarDeger& d) { fikoUiAyar().boslukY = (f32)d.f; }}); s.ayarKaydet({.kimlik = "arayuz.kose", .kategori = "Arayüz", .ad = "Köşe yuvarlaklığı", .aciklama = "Pencere/çerçeve köşe yarıçapı (0 keskin – 12 yuvarlak).", .tip = AyarTip::F64, .varsayilan = dF(4.0), .min = 0.0, .maks = 12.0, .al = [] { return dF(fikoUiAyar().kosePolisi); }, .ata = [](const AyarDeger& d) { fikoUiAyar().kosePolisi = (f32)d.f; }}); s.ayarKaydet({.kimlik = "arayuz.cam_alfa", .kategori = "Arayüz", .ad = "Cam saydamlığı", .aciklama = "Cam pencerelerin (CAD Fark vb.) aeroglass zemin saydamlığı. " "Düşük = arka sahne net görünür; yüksek = daha opak.", .tip = AyarTip::F64, .varsayilan = dF(0.58), .min = 0.15, .maks = 1.0, .al = [] { return dF(fikoUiAyar().camAlfa); }, .ata = [](const AyarDeger& d) { fikoUiAyar().camAlfa = (f32)d.f; }}); s.ayarKaydet({.kimlik = "arayuz.koyu_tema", .kategori = "Arayüz", .ad = "Koyu cam tema", .aciklama = "Cam pencereler koyu neon tonda (varsayılan açık cam).", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(fikoUiAyar().koyuTema); }, .ata = [](const AyarDeger& d) { fikoUiAyar().koyuTema = d.b; }}); } void kaydetFark(AyarSistemi& s) { s.ayarKaydet({.kimlik = "fark.gpu_kullan", .kategori = "CAD Fark", .ad = "GPU hızlandırma", .aciklama = "Model karşılaştırma mesafe hesabını GPU compute'ta koşar " "(milyon vertex tek seferde — CPU'ya göre kat kat hızlı). " "Kapalı/başarısız → çok çekirdekli CPU (sonuç birebir aynı).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(farkGpuKullan()); }, .ata = [](const AyarDeger& d) { farkGpuKullan() = d.b; }}); s.ayarKaydet({.kimlik = "fark.tur_sure", .kategori = "CAD Fark", .ad = "Sinematik tur süresi (sn/bölge)", .aciklama = "Fark turunda kameranın her değişim bölgesinde kalma süresi. " "Büyük = sakin sunum; küçük = hızlı gezinti.", .tip = AyarTip::F64, .varsayilan = dF(farkTurSaniye()), .min = 1.0, .maks = 30.0, .al = [] { return dF(farkTurSaniye()); }, .ata = [](const AyarDeger& d) { farkTurSaniye() = d.f; }}); s.ayarKaydet({.kimlik = "fark.isaretci_azami", .kategori = "CAD Fark", .ad = "Bölge işaretçisi üst sınırı", .aciklama = "Sahnede aynı anda gösterilecek en fazla numaralı değişim bölgesi " "işaretçisi (tur kapalıyken). Büyük = tüm bölgeler; küçük = ekran " "daha sade.", .tip = AyarTip::Int, .varsayilan = dInt(farkIsaretciAzami()), .min = 0, .maks = 200, .al = [] { return dInt(farkIsaretciAzami()); }, .ata = [](const AyarDeger& d) { farkIsaretciAzami() = (int)d.i; }}); s.ayarKaydet({.kimlik = "fark.bolge_min_vertex", .kategori = "CAD Fark", .ad = "Bölge asgari vertex", .aciklama = "Bir değişim kümesinin 'bölge' sayılması için gereken en az vertex. " "Altındaki küçük kümeler gürültü sayılıp tura/listeye girmez.", .tip = AyarTip::Int, .varsayilan = dInt(farkBolgeMinVertex()), .min = 1, .maks = 10000, .al = [] { return dInt(farkBolgeMinVertex()); }, .ata = [](const AyarDeger& d) { farkBolgeMinVertex() = (int)d.i; }}); s.ayarKaydet({.kimlik = "fark.skala_yuzdelik", .kategori = "CAD Fark", .ad = "Renk skalası yüzdeliği", .aciklama = "Renk skalası ± ucunun başlangıç değeri, sapmaların bu yüzdeliği " "olur (0.95 = P95). Düşük = aykırı büyük sapmalar skalayı ele " "geçirmez, ince farklar daha renkli; 0.99 = klasik P99.", .tip = AyarTip::F64, .varsayilan = dF(farkSkalaYuzdelik()), .min = 0.80, .maks = 0.999, .al = [] { return dF(farkSkalaYuzdelik()); }, .ata = [](const AyarDeger& d) { farkSkalaYuzdelik() = (f32)d.f; }}); s.ayarKaydet({.kimlik = "fark.oto_tolerans", .kategori = "CAD Fark", .ad = "Otomatik değişim eşiği (köşegen oranı)", .aciklama = "Eklenen/silinen bölge sınıflandırma eşiği = model köşegeni × bu " "oran. Büyük = yalnız iri farklar değişim sayılır; küçük = ince " "farklar da yakalanır (gürültüye duyarlı).", .tip = AyarTip::F64, .varsayilan = dF(farkOtoToleransCarpan()), .min = 0.00001, .maks = 0.1, .al = [] { return dF(farkOtoToleransCarpan()); }, .ata = [](const AyarDeger& d) { farkOtoToleransCarpan() = d.f; }}); } void kaydetSecim(AyarSistemi& s) { // Akıllı seçim toleransları (brep yayılım fonksiyonlarının girdisi). s.ayarKaydet({.kimlik = "secim.akilli_aci_tol", .kategori = "Seçim", .ad = "Akıllı seçim açı toleransı (°)", .aciklama = "Teğet/koplanar/paralel yüz yayılımında normaller bu açı içindeyse " "aynı kümeye alınır. Büyütmek seçimi genişletir.", .tip = AyarTip::F32, .varsayilan = dF(1.0), .min = 0.0, .maks = 90.0, .al = [] { return dF(akilliSecimAciTol()); }, .ata = [](const AyarDeger& d) { akilliSecimAciTolAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "secim.akilli_kenar_tol", .kategori = "Seçim", .ad = "Kenar zinciri teğet toleransı (°)", .aciklama = "Kenar loop yayılımında komşu kenarın teğeti bu açı içindeyse " "zincire katılır (çevre filleti tek komutla seçilir).", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = 0.0, .maks = 90.0, .al = [] { return dF(akilliSecimKenarTol()); }, .ata = [](const AyarDeger& d) { akilliSecimKenarTolAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "secim.akilli_boyut_tol", .kategori = "Seçim", .ad = "Benzer öğe ölçü toleransı", .aciklama = "\"Bu çaptaki tüm delikler\" / \"bu R'deki tüm kenarlar\" eşleşmesi: " "yarıçapta MUTLAK (mm), alanda ORAN.", .tip = AyarTip::F32, .varsayilan = dF(1e-3), .min = 0.0, .maks = 100.0, .al = [] { return dF(akilliSecimBoyutTol()); }, .ata = [](const AyarDeger& d) { akilliSecimBoyutTolAta((f32)d.f); }}); s.ayarKaydet({.kimlik = "secim.bvh_arkaplan", .kategori = "Seçim", .ad = "BVH arka-plan kurulumu", .aciklama = "Büyük modelin ışın-BVH'si (hover/seçim raycast hızlandırıcısı) içe " "aktarım sonrası ARKA PLANDA çok çekirdekli kurulur → ilk hover'da " "donma olmaz. Kurulum sürerken yüz hover'ı geçici GPU pick ile çözülür. " "Kapalı = eski davranış (ilk hover'da senkron kurulum).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(bvhArkaplan()); }, .ata = [](const AyarDeger& d) { bvhArkaplan() = d.b; }}); s.ayarKaydet({.kimlik = "secim.derinlik_ortme", .kategori = "Seçim", .ad = "Örtülen kenar/noktayı bastır", .aciklama = "Önde yüzey varken ARKASINDA kalan kenar/nokta hover'da seçilmez " "(profesyonel CAD davranışı). Kapalı = duvar arkası kenarlar da " "seçilebilir (eski davranış).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(pickAyar().derinlikOrtme); }, .ata = [](const AyarDeger& d) { pickAyar().derinlikOrtme = d.b; }}); s.ayarKaydet({.kimlik = "secim.kesit_kirp", .kategori = "Seçim", .ad = "Kesit dışında kalanı seçme", .aciklama = "Kesit düzlemi aktifken KIRPILAN (ekranda görünmeyen) yüzey/kenar " "tıklanmaz, ölçüm oraya tutunmaz — ışın devam eder, kesitin " "gösterdiği asıl yüzey seçilir. Kapalı = eski davranış " "(görünmeyen yüzey de seçilebilir).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(pickAyar().kesitKirp); }, .ata = [](const AyarDeger& d) { pickAyar().kesitKirp = d.b; }}); s.ayarKaydet({.kimlik = "secim.orta_merkez_akilli", .kategori = "Seçim", .ad = "Akıllı merkezleme/zoom pivotu", .aciklama = "Orta-tık merkezleme ve tekerlek zoom, ışın yüzeye vurmazsa imleç " "altındaki gövdenin (GPU pick ile çözülen) merkezine pivotlar. " "Uzaktaki parça (BVH henüz kurulmamışken bile) doğru merkezlenir ve " "orbit pivotu parçanın içinde kalır → kamera parçaya dalmaz. Kapalı = " "eski davranış (yüzey vurmazsa havada bir noktaya merkezler).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(pickAyar().ortaMerkezAkilli); }, .ata = [](const AyarDeger& d) { pickAyar().ortaMerkezAkilli = d.b; }}); s.ayarKaydet({.kimlik = "secim.yol_secilemez", .kategori = "Seçim", .ad = "CAM takım yolu seçilemez", .aciklama = "Takım yolu bir görselleştirmedir, seçilebilir geometri değil. " "Açık: sahnede hover/seçim almaz — 200k+ vertexli yolun " "\"komple seçili\" gibi parlaması ve her hover'daki O(kenar) " "taraması biter. Kapalı = eski davranış (yol seçilebilir).", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(pickAyar().yolSecilemez); }, .ata = [](const AyarDeger& d) { pickAyar().yolSecilemez = d.b; }}); s.ayarKaydet({.kimlik = "secim.imlec_bolge_kult", .kategori = "Seçim", .ad = "İmleç-bölge pick kültü (deneysel)", .aciklama = "Hover/seçim geçişinde yalnız imleç çevresindeki nesneleri işle → " "yoğun sahnede hover hızlanır (draw-call düşer). Seçim doğruluğu " "korunmalı; bir sorun görürsen kapat.", .tip = AyarTip::Bool, .varsayilan = dBool(false), .al = [] { return dBool(pickAyar().imlecBolgeKult); }, .ata = [](const AyarDeger& d) { pickAyar().imlecBolgeKult = d.b; }}); s.ayarKaydet({.kimlik = "secim.pick_yaricap", .kategori = "Seçim", .ad = "Yakalama yarıçapı (px)", .aciklama = "İmleç çevresinde kenar/nokta arama yarıçapı. Büyük = kolay yakalar " "ama yüzey seçimi kenarlara yapışır. 0 = tam piksel.", .tip = AyarTip::Int, .varsayilan = dInt(4), .min = 0, .maks = 8, .al = [] { return dInt(pickAyar().yaricap); }, .ata = [](const AyarDeger& d) { pickAyar().yaricap = (i32)d.i; }}); s.ayarKaydet({.kimlik = "secim.kenar_bias", .kategori = "Seçim", .ad = "Kenar/nokta öne alma", .aciklama = "Kenar/nokta pick'ini yüzeylerin önüne alır (daha negatif = daha " "öne). Dipteki kesişen kenarları seçilebilir yapar; çok fazla olursa " "duvar arkası kenarlar da seçilir.", .tip = AyarTip::F32, .varsayilan = dF(-4.0), .min = -16, .maks = 0, .al = [] { return dF(pickAyar().kenarBias); }, .ata = [](const AyarDeger& d) { pickAyar().kenarBias = (f32)d.f; }}); s.ayarKaydet({.kimlik = "secim.yuz_bias", .kategori = "Seçim", .ad = "Yüz geriye itme", .aciklama = "Yüz pick'ini geriye iter → paylaşılan kenarlarda kenar/nokta öne " "çıkar (render ile aynı ayrım).", .tip = AyarTip::F32, .varsayilan = dF(2.0), .min = 0, .maks = 8, .al = [] { return dF(pickAyar().yuzBias); }, .ata = [](const AyarDeger& d) { pickAyar().yuzBias = (f32)d.f; }}); s.ayarKaydet({.kimlik = "yigin.tolerans", .kategori = "Seçim Yığını", .ad = "Kenar/nokta yakalama (px)", .aciklama = "Alt+tık yığınında kenar/nokta ekran-uzayı yakalama toleransı. " "Büyük = imleç altındaki daha uzak kenar/noktaları da listeler.", .tip = AyarTip::F32, .varsayilan = dF(9.0), .min = 2, .maks = 30, .al = [] { return dF(secimGorunum().yiginTol); }, .ata = [](const AyarDeger& d) { secimGorunum().yiginTol = (f32)d.f; }}); s.ayarKaydet({.kimlik = "yigin.peek", .kategori = "Seçim Yığını", .ad = "Peek lens (occluder'sız)", .aciklama = "Yığın açıkken sabit imleç dairesinde aktif adayı önündeki elemanlar " "olmadan (X-ray) göster.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(secimGorunum().peekAcik); }, .ata = [](const AyarDeger& d) { secimGorunum().peekAcik = d.b; }}); s.ayarKaydet({.kimlik = "yigin.peek_yari", .kategori = "Seçim Yığını", .ad = "Peek daire yarıçapı (px)", .aciklama = "Peek lens dairesinin ekran yarıçapı.", .tip = AyarTip::F32, .varsayilan = dF(45.0), .min = 12, .maks = 120, .al = [] { return dF(secimGorunum().peekYari); }, .ata = [](const AyarDeger& d) { secimGorunum().peekYari = (f32)d.f; }}); s.ayarKaydet({.kimlik = "secim.renk", .kategori = "Seçim", .ad = "Seçim vurgu rengi", .aciklama = "Seçili yüz/kenar/nokta vurgu rengi (varsayılan turuncu).", .tip = AyarTip::Renk, .varsayilan = dRenk(Vec3f{1.0f, 0.45f, 0.05f}), .al = [] { return dRenk(secimGorunum().secimRenk); }, .ata = [](const AyarDeger& d) { secimGorunum().secimRenk = d.renk; }}); s.ayarKaydet({.kimlik = "secim.hover_renk", .kategori = "Seçim", .ad = "Hover vurgu rengi", .aciklama = "İmleç-altı öğe vurgu rengi (varsayılan cyan).", .tip = AyarTip::Renk, .varsayilan = dRenk(Vec3f{0.25f, 0.85f, 1.0f}), .al = [] { return dRenk(secimGorunum().hoverRenk); }, .ata = [](const AyarDeger& d) { secimGorunum().hoverRenk = d.renk; }}); s.ayarKaydet({.kimlik = "secim.nabiz_hiz", .kategori = "Seçim", .ad = "Yanıp-sönme hızı", .aciklama = "Seçim vurgusunun nabız hızı (0 = ~sabit). Yüz+kenar+nokta ortak.", .tip = AyarTip::F32, .varsayilan = dF(5.0), .min = 0, .maks = 15, .al = [] { return dF(secimGorunum().nabizHiz); }, .ata = [](const AyarDeger& d) { secimGorunum().nabizHiz = (f32)d.f; }}); s.ayarKaydet({.kimlik = "secim.nabiz_siddet", .kategori = "Seçim", .ad = "Yanıp-sönme şiddeti", .aciklama = "Nabız genliği (0 = yanıp sönme yok, sabit renk).", .tip = AyarTip::F32, .varsayilan = dF(0.15), .min = 0, .maks = 0.5, .al = [] { return dF(secimGorunum().nabizSiddet); }, .ata = [](const AyarDeger& d) { secimGorunum().nabizSiddet = (f32)d.f; }}); s.ayarKaydet({.kimlik = "gorunum.cift_tarafli", .kategori = "Görünüm", .ad = "Çift-taraflı model render", .aciklama = "Açık: ters/tutarsız winding'li (aynalı/ithal) modeller \"şeffaf yüz\" " "göstermez (görünürlüğü derinlik belirler). Kapalı: arka-yüz ayıklamalı " "— biraz daha hızlı ama bozuk modelde içi görünebilir.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [] { return dBool(secimGorunum().ciftTarafli); }, .ata = [](const AyarDeger& d) { secimGorunum().ciftTarafli = d.b; }}); } void kaydetAgacSimgeleri(AyarSistemi& s) { // Merkezî kayıt (motor/ui): boş → sağlayıcının glifi; değer verilince override. // Generic (govde/sketch/datum…) + tüm Part Design feature'ları + GSD tipleri → // Ayarlar'da tek tek seçilebilir (tek "Simgeler" kategorisi, sağda sekmeli). ui::agacSimgeVarsayilanlariKur(); for (const parca::FeatureTanim& t : parca::featureTanimlari()) ui::AgacSimgeKayit::global().kaydet(("feature." + t.id).c_str(), t.ad.c_str(), t.simge.c_str()); for (const parca::FeatureTanim& t : gsd::gsdTanimlari()) ui::AgacSimgeKayit::global().kaydet(("gsd." + t.id).c_str(), t.ad.c_str(), t.simge.c_str()); for (ui::AgacSimgeKayit::Giris& g : ui::AgacSimgeKayit::global().girisler()) { const std::string anah = g.anahtar; s.ayarKaydet({.kimlik = "simge." + anah, .kategori = "Simgeler", .ad = g.ad, .aciklama = "Emoji (örn. 📐) VEYA .svg/.png/.jpg dosya yolu. Boş → " "varsayılan tip glifi (örn. " + g.varsayilan + ").", .tip = AyarTip::Metin, .varsayilan = dMetin(""), .al = [anah] { return dMetin(ui::AgacSimgeKayit::global().hamDeger(anah.c_str())); }, .ata = [anah](const AyarDeger& d) { ui::AgacSimgeKayit::global().ayarla(anah.c_str(), d.metin); }}); } } // Birim küsüratları (Ayarlar → Birimler): her CAD/CAM birimi için ondalık hane. // mm ve derece varsayılan 3. Değer değişince fiko::birim canlı güncellenir; bağlı // dinleyici (ayarlarKaydet'te) ölçü metinlerini tazeler → her yerde aynı hassasiyet. void kaydetBirimler(AyarSistemi& s) { using birim::Birim; struct Kayit { Birim b; const char* kimlik; }; static const Kayit kayitlar[] = { {Birim::Uzunluk, "birim.uzunluk_hane"}, {Birim::Aci, "birim.aci_hane"}, {Birim::Alan, "birim.alan_hane"}, {Birim::Hacim, "birim.hacim_hane"}, {Birim::Koordinat, "birim.koordinat_hane"}, {Birim::Ilerleme, "birim.ilerleme_hane"}, {Birim::Devir, "birim.devir_hane"}, {Birim::Oran, "birim.oran_hane"}, {Birim::Sure, "birim.sure_hane"}, }; for (const Kayit& k : kayitlar) { const Birim bir = k.b; s.ayarKaydet({.kimlik = k.kimlik, .kategori = "Birimler", .ad = birim::ad(bir), .aciklama = "Bu birimin ekranda gösterilen ondalık hane (küsürat) sayısı. " "Ölçüm, hover, analiz ve CAM — nerede gösterilirse geçerli.", .tip = AyarTip::Int, .varsayilan = dInt(birim::haneVarsayilan(bir)), .min = 0, .maks = 8, .al = [bir] { return dInt(birim::hane(bir)); }, .ata = [bir](const AyarDeger& d) { birim::haneAta(bir, (int)d.i); birim::degistiBildir(); // ölçü metinlerini tazele + kare iste }}); } } } // namespace u32 dokumVarsayilanCozunurluk() { return g_dokumCozunurluk; } bool dokumVoxelKirp() { return g_dokumVoxelKirp; } f32 dokumKapsamaEsik() { return g_dokumKapsamaEsik; } bool dokumSphDivergenceCozucu() { return g_dokumSphDivergence; } u32 dokumSphMaksPartikul() { return g_dokumSphMaksPartikul; } f64 dokumGirisKutlePay() { return g_dokumGirisKutlePay; } f64 dokumGirisUzakEsikH() { return g_dokumGirisUzakEsikH; } f64 dokumCidarYuzdelik() { return g_dokumCidarYuzdelik; } f64 dokumKapsamaSismeEsik() { return g_dokumKapsamaSisme; } bool dokumPoroziteOtoEsik() { return g_dokumPorOtoEsik; } f64 dokumPoroziteYuzdelik() { return g_dokumPorYuzdelik; } f64 dokumDereceKumSaydamlik() { return g_dokumDereceKumSaydamlik; } f64 dokumKumYogunluk() { return g_dokumKumYogunluk; } void dokumDereceVarsayilanUygula(dokum::Derece& d) { d.goster = g_dokumDereceGoster; d.tekParca = g_dokumDereceTekParca; d.kumPayMm = g_dokumDereceKumPay; d.ustPayMm = g_dokumDereceUstPay; d.altPayMm = g_dokumDereceAltPay; d.duvarMm = g_dokumDereceDuvar; } bool dokumPartikulKaydet() { return g_dokumPartikulKaydet; } u32 dokumPartikulAltOrnek() { return g_dokumPartikulAltOrnek; } f32 dokumPartikulYaricapOran() { return g_dokumPartikulYaricapOran; } u32 dokumPartikulCizAltOrnek() { return g_dokumPartikulCizAltOrnek; } f64 straforVarsayilanHedefEn() { return g_straforHedefEn; } f64 straforVarsayilanHedefBoy() { return g_straforHedefBoy; } f64 straforVarsayilanHedefYuk() { return g_straforHedefYuk; } bool straforGeciciOncelik() { return g_straforGeciciOncelik; } u32 straforVaryantSayisi() { return g_straforVaryant; } bool straforOffcutNesting() { return g_straforOffcutNesting; } bool aptIthalSimulasyon() { return g_aptIthalSim; } bool aptAktiviteAyir() { return g_aptAktiviteAyir; } bool zekaAktif() { return g_zekaAktif; } bool zekaHesapAsync() { return g_zekaHesapAsync; } uint64_t orkestraYanitsizEsikMs() { return g_orkestraYanitsizMs; } uint64_t orkestraOfflineEsikMs() { return g_orkestraOfflineMs; } uint64_t orkestraTazelemeMs() { return g_orkestraTazelemeMs; } bool orkestraLanKesif() { return g_orkestraLanKesif; } uint16_t orkestraLanPort() { return (uint16_t)g_orkestraLanPort; } uint64_t orkestraBeaconSn() { return g_orkestraBeaconSn; } uint64_t orkestraMetrikAralikMs() { return g_orkestraMetrikMs; } uint16_t orkestraTcpPort() { return (uint16_t)g_orkestraTcpPort; } uint32_t orkestraTcpMaksBaglanti() { return (uint32_t)g_orkestraTcpMaksBag; } uint64_t orkestraTcpMaksGovdeMB() { return (uint64_t)g_orkestraTcpMaksGovdeMB; } uint64_t orkestraEslesmeTtlSn() { return g_orkestraEslesmeTtlSn; } uint32_t orkestraTransferParcaKB() { return (uint32_t)g_orkestraTransferParcaKB; } bool istakipKral() { return g_istakipKral; } uint16_t istakipPort() { return (uint16_t)g_istakipPort; } std::string istakipKralAdres() { return g_istakipKralAdres; } std::string istakipMongoUri() { return g_istakipMongoUri; } bool istakipIstemciYazabilir() { return g_istakipIstemciYazabilir; } bool istakipKimlikDogrulama() { return g_istakipKimlik; } uint64_t istakipSnapshotParca() { return (uint64_t)g_istakipSnapshotParca; } orkestra::YerlestirmeAgirlik orkestraYerlestirmeAgirlik() { return {.cpu = g_orkestraPuanCpu / 100.f, .task = g_orkestraPuanTask / 100.f, .bellek = g_orkestraPuanBellek / 100.f, .taskDoyum = (uint32_t)g_orkestraPuanDoyum}; } f64 aptYayTolerans() { return g_aptYayTolerans; } f64 straforIscilikAgirlik() { return g_straforIscilikAgirlik; } void ayarlarKaydet(UygulamaBaglam& b, AyarlarPencereDurum& pencere) { AyarSistemi& s = ayar::sistem(); Cekirdek* c = &b.cekirdek; kaydetAgacSimgeleri(s); kaydetAgac(s, b); kaydetGorunum(s, b, c); kaydetPerformans(s); kaydetAydinlatma(s, b); kaydetIzgara(s, b); kaydetSketcher(s, b); kaydetKamera(s, b); kaydetDokunmatik(s); kaydetMenuOgrenme(s); kaydetMakro(s); // kaydetYardim (GPU hızlandırma ayarı) KAYDEDİLMİYOR: shared texture bu CEF/GPU'da // çalışmıyor (07-17 ölçüldü) → software sabitlendi (main.cpp). Backend desteklenince // hem bu kayıt hem main'deki yardimCefGpuHizliAyarla(false) geri açılır. kaydetNavGhost(s); kaydetFeatureOnizleme(s); kaydetDogrudan(s); kaydetHizli3d(s, b); kaydetDokum(s); kaydetStrafor(s); kaydetSecim(s); kaydetFark(s); kaydetArayuz(s); kaydetPencere(s); kaydetBirimler(s); // Birim küsüratı değişince aktif ölçü metinlerini tazele + kare iste (canlı). birim::degistiDinle([o = &b.olcum] { o->metinleriYenile(); kareIste(); }); kaydetKesit(s, b); kaydetUndercut(s, b); kaydetZeka(s, b); kaydetEklenti(s); // ---- Alt Toolbar kişiselleştirme ---- // toolbarAyar() belge_penceresi.cpp'deki static ToolbarAyar nesnesine erişir. // Tüm değerler kalıcı (ayar. öneki) ve canlı (değişiklik anında yansır). { auto& tb = toolbarAyar(); s.ayarKaydet({.kimlik = "toolbar.goster", .kategori = "Toolbar", .ad = "Toolbar göster", .aciklama = "Alt toolbar'ı göster / gizle.", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [&tb] { return dBool(tb.goster); }, .ata = [&tb](const AyarDeger& d) { tb.goster = d.b; }}); s.ayarKaydet({.kimlik = "toolbar.dugme_cap", .kategori = "Toolbar", .ad = "Düğme boyutu (px)", .aciklama = "Her düğmenin genişlik/yüksekliği.", .tip = AyarTip::F32, .varsayilan = dF(24.0f), .min = 16.0, .maks = 48.0, .al = [&tb] { return dF(tb.dugmeCap); }, .ata = [&tb](const AyarDeger& d) { tb.dugmeCap = (float)d.f; }}); s.ayarKaydet({.kimlik = "toolbar.aralik", .kategori = "Toolbar", .ad = "Düğmeler arası boşluk (px)", .tip = AyarTip::F32, .varsayilan = dF(4.0f), .min = 0.0, .maks = 20.0, .al = [&tb] { return dF(tb.aralik); }, .ata = [&tb](const AyarDeger& d) { tb.aralik = (float)d.f; }}); s.ayarKaydet({.kimlik = "toolbar.ic_pay", .kategori = "Toolbar", .ad = "İç kenar boşluğu (px)", .aciklama = "Toolbar içindeki üst/alt/yan pad.", .tip = AyarTip::F32, .varsayilan = dF(6.0f), .min = 2.0, .maks = 20.0, .al = [&tb] { return dF(tb.icPay); }, .ata = [&tb](const AyarDeger& d) { tb.icPay = (float)d.f; }}); s.ayarKaydet({.kimlik = "toolbar.alt_bosluk", .kategori = "Toolbar", .ad = "Ekran altından mesafe (px)", .aciklama = "Toolbar'ın ekran alt kenarından uzaklığı.", .tip = AyarTip::F32, .varsayilan = dF(4.0f), .min = 0.0, .maks = 60.0, .al = [&tb] { return dF(tb.altBosluk); }, .ata = [&tb](const AyarDeger& d) { tb.altBosluk = (float)d.f; }}); s.ayarKaydet({.kimlik = "toolbar.kenar_pay", .kategori = "Toolbar", .ad = "Ekran kenar boşluğu (px)", .aciklama = "Sol/sağ kenar dışına taşmama payı.", .tip = AyarTip::F32, .varsayilan = dF(16.0f), .min = 0.0, .maks = 120.0, .al = [&tb] { return dF(tb.kenarPay); }, .ata = [&tb](const AyarDeger& d) { tb.kenarPay = (float)d.f; }}); s.ayarKaydet({.kimlik = "toolbar.saydamlik", .kategori = "Toolbar", .ad = "Saydamlık (alfa)", .aciklama = "0 = tamamen saydam, 1 = tamamen opak.", .tip = AyarTip::F32, .varsayilan = dF(0.82f), .min = 0.05, .maks = 1.0, .al = [&tb] { return dF(tb.saydamlik); }, .ata = [&tb](const AyarDeger& d) { tb.saydamlik = (float)d.f; }}); s.ayarKaydet({.kimlik = "toolbar.border_kalinlik", .kategori = "Toolbar", .ad = "Border kalınlığı (px)", .aciklama = "0 = border yok.", .tip = AyarTip::F32, .varsayilan = dF(1.0f), .min = 0.0, .maks = 4.0, .al = [&tb] { return dF(tb.borderKalinlik); }, .ata = [&tb](const AyarDeger& d) { tb.borderKalinlik = (float)d.f; }}); s.ayarKaydet({.kimlik = "toolbar.bg_renk", .kategori = "Toolbar", .ad = "Arka plan rengi", .aciklama = "Toolbar arka plan rengi (saydamlık ayrı ayarlanır).", .tip = AyarTip::Renk, .varsayilan = dRenk({0.11f, 0.12f, 0.13f}), .al = [&tb] { return dRenk({tb.bgR, tb.bgG, tb.bgB}); }, .ata = [&tb](const AyarDeger& d) { tb.bgR = d.renk.x; tb.bgG = d.renk.y; tb.bgB = d.renk.z; }}); s.ayarKaydet({.kimlik = "toolbar.border_renk", .kategori = "Toolbar", .ad = "Border rengi", .aciklama = "Çerçeve çizgi rengi (opaklık ayrı ayarlanır).", .tip = AyarTip::Renk, .varsayilan = dRenk({1.0f, 1.0f, 1.0f}), .al = [&tb] { return dRenk({tb.borderR, tb.borderG, tb.borderB}); }, .ata = [&tb](const AyarDeger& d) { tb.borderR = d.renk.x; tb.borderG = d.renk.y; tb.borderB = d.renk.z; }}); } kaydetLisans(s); kaydetArac(s); kaydetGuncelleme(s); kaydetGeriBildirim(s); kaydetGecici(s); kaydetOtoKayit(s); kaydetPafta(s); kaydetPmi(s); kaydetPmiOrtme(s); // ---- Değişiklik köprüsü: kalıcı yaz (+ AyarDegisti olayı — kontrat) ---- s.degisti = [c](const AyarTanim& t, const AyarDeger& d) { if (t.kimlik == TEMA_KIMLIK) return; // tema "tema" anahtarında kalıcı (main.cpp) ayarYaz(("ayar." + t.kimlik).c_str(), AyarSistemi::degerMetni(t, d)); // KONTRAT: olay.hpp'ye AyarDegisti eklendiğinde aşağıdaki satır açılır: c->olaylar().yayinla(AyarDegisti{t.kimlik.c_str()}, t.kimlik.c_str()); (void)c; }; // ---- Kalıcı değerleri uygula (sessiz — köprü tetiklenmez, olay yayılmaz) ---- for (const AyarTanim& t : s.hepsi()) { if (t.kimlik == TEMA_KIMLIK) continue; const std::string v = ayarOku(("ayar." + t.kimlik).c_str(), ""); if (v.empty()) continue; AyarDeger d = t.varsayilan; if (AyarSistemi::degerCoz(t, v, d)) t.ata(d); } // ---- Menü komutları ---- b.cekirdek.menuler().ekle({.grup = "Araçlar", .ad = "⚙ Ayarlar…", .simge = "⚙", .sira = 900, .calistir = [p = &pencere](Cekirdek&) { p->acik = true; }}); b.cekirdek.menuler().ekle( {.grup = "Araçlar", .ad = "🧹 Geçici dosyaları temizle", .simge = "🧹", .sira = 910, .calistir = [ub = &b](Cekirdek&) { const u64 silinen = gecici::temizle(); ub->bilgiVer(std::format("Geçici dosyalar temizlendi ({:.1f} MB) — {}", (f64)silinen / (1024.0 * 1024.0), gecici::kok().string())); }}); // ---- Açılış bakımı: politikayı arka planda uygula (dizin taraması sıcak yolda değil) ---- if (geciciAcilistaBuda()) b.cekirdek.gorevler().kuyrukla("Geçici bakım", [](GorevBaglam&) { geciciBakimYap(); }, [] {}); } bool ozmoKafaAyrilikProses() { return g_ozmo_kafa_ayrilik_proses; } bool diagonalKafaAyrilikProses() { return g_diagonal_kafa_ayrilik_proses; } } // namespace fiko