// Topolojik öğe görsel özellikleri (Dalga 1): veri modeli + çözüm + undo + STEP köprü. // Vulkan gerektirmez — Dugum/DugumPusula ve saf yardımcılar doğrudan test edilir. #include "fiko/geometri/brep.hpp" #include "fiko/sahne/oge_ozellik.hpp" #include "fiko/sahne/sahne.hpp" #include "fiko/sahne/sketch_nesne.hpp" // sketchKontur2d (sketch-on-surface 2D profil çıkarıcı) #include "fiko_test.hpp" using namespace fiko; // ---- Task 1: tip-bazlı görsel varsayılan ---- FIKO_TEST(oge_varsayilan_tip_bazli) { const OgeOzellik yuz = ogeVarsayilan(OgeTip::Yuz); const OgeOzellik kenar = ogeVarsayilan(OgeTip::Kenar); const OgeOzellik nokta = ogeVarsayilan(OgeTip::Nokta); FIKO_YAKIN(yuz.alfa, 1.0f, 1e-6f); FIKO_KONTROL(yuz.gorunur); FIKO_KONTROL(kenar.stil == KenarStil::Duz); FIKO_KONTROL(kenar.kalinlik > 0.0f); FIKO_KONTROL(nokta.sekil == NoktaSekil::Nokta); FIKO_KONTROL(nokta.noktaBoyut > 0.0f); // Kenar varsayılanı yüzden koyu (görsel ayrım). FIKO_KONTROL(kenar.renk.x < yuz.renk.x || kenar.renk.y < yuz.renk.y); } // ---- Task 2: Dugum per-öğe özellik deposu + çözüm ---- FIKO_TEST(dugum_ozellik_cozum) { Dugum d; // Override yok → gövde varsayılanı (yüz). const OgeOzellik c0 = d.yuzOzellik(3); FIKO_YAKIN(c0.renk.x, ogeVarsayilan(OgeTip::Yuz).renk.x, 1e-6f); // Yüz 3'e kırmızı ata → çözümde kırmızı döner, yüz 5 hâlâ varsayılan. d.yuzOzellikYaz(3).renk = {1.0f, 0.0f, 0.0f}; FIKO_YAKIN(d.yuzOzellik(3).renk.x, 1.0f, 1e-6f); FIKO_YAKIN(d.yuzOzellik(5).renk.x, ogeVarsayilan(OgeTip::Yuz).renk.x, 1e-6f); // Gövde varsayılanı değişince override'sız öğeler etkilenir; override korunur. d.yuzVars.alfa = 0.5f; FIKO_YAKIN(d.yuzOzellik(5).alfa, 0.5f, 1e-6f); FIKO_YAKIN(d.yuzOzellik(3).alfa, 1.0f, 1e-6f); // Kenar/nokta depoları bağımsız çözülür. d.kenarOzellikYaz(1).kalinlik = 4.0f; FIKO_YAKIN(d.kenarOzellik(1).kalinlik, 4.0f, 1e-6f); FIKO_YAKIN(d.kenarOzellik(2).kalinlik, ogeVarsayilan(OgeTip::Kenar).kalinlik, 1e-6f); d.noktaOzellikYaz(1).noktaBoyut = 12.0f; FIKO_YAKIN(d.noktaOzellik(1).noktaBoyut, 12.0f, 1e-6f); } // ---- Task 3: undo/redo kalıcılığı (DugumPusula öğe özellik taşıma) ---- // Sahne::anlik/diril Vulkan gerektirir; taşımanın TEK KAYNAĞI olan saf yardımcılar // (ogeOzellikPusulaya/ogeOzellikDugume — anlik/diril bunları çağırır) doğrudan test edilir. FIKO_TEST(ozellik_undo_roundtrip) { Dugum d; d.yuzOzellikYaz(2).renk = {0.1f, 0.9f, 0.2f}; d.kenarOzellikYaz(4).kalinlik = 3.3f; d.yuzVars.alfa = 0.4f; // Pusula al (undo snapshot). DugumPusula p; ogeOzellikPusulaya(d, p); // "Başka işlem" → renk kaybı simülasyonu. d.yuzOz.clear(); d.kenarOz.clear(); d.yuzVars = ogeVarsayilan(OgeTip::Yuz); FIKO_YAKIN(d.yuzOzellik(2).renk.y, ogeVarsayilan(OgeTip::Yuz).renk.y, 1e-6f); // kayıp // Dirilt (undo) → geri gelir. ogeOzellikDugume(p, d); FIKO_YAKIN(d.yuzOzellik(2).renk.y, 0.9f, 1e-6f); FIKO_YAKIN(d.kenarOzellik(4).kalinlik, 3.3f, 1e-6f); FIKO_YAKIN(d.yuzVars.alfa, 0.4f, 1e-6f); } // ---- Task 4: STEP yüz renkleri → yuzOz köprüsü ---- FIKO_TEST(step_yuz_renk_kopru) { auto brep = geometri::kutu(2.0, 2.0, 2.0); brep.yuzRenkleriAta({{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}); Dugum d; ogeOzellikBrepYuzRenkUygula(d, brep); // 1-tabanlı ordinal: yuzRenkleri[i-1] → yuzOzellik(i). FIKO_YAKIN(d.yuzOzellik(1).renk.x, 1.0f, 1e-5f); FIKO_YAKIN(d.yuzOzellik(2).renk.y, 1.0f, 1e-5f); FIKO_YAKIN(d.yuzOzellik(3).renk.z, 1.0f, 1e-5f); // Renk atanmamış yüz → gövde varsayılanı. FIKO_YAKIN(d.yuzOzellik(9).renk.x, ogeVarsayilan(OgeTip::Yuz).renk.x, 1e-5f); } // ---- Sketch-on-Surface: sketchKontur2d 2D profil çıkarıcı ---- FIKO_TEST(sketch_kontur2d_kare_tek_kapali) { eskiz::EskizVeri ev; // merkezli 4×4 kare — 4 çizgi uç-uca ev.cizgiEkle(-2, -2, 2, -2); ev.cizgiEkle(2, -2, 2, 2); ev.cizgiEkle(2, 2, -2, 2); ev.cizgiEkle(-2, 2, -2, -2); std::vector k; FIKO_KONTROL(sketchKontur2d(ev, k)); FIKO_KONTROL(k.size() == 1); // tek kapalı kontur FIKO_KONTROL(k[0].size() == 4); // 4 çizgi segmenti FIKO_KONTROL(k[0][0].tip == geometri::ProfilEgri2d::Tip::Cizgi); } FIKO_TEST(sketch_kontur2d_cember_kapali_tek_egri) { eskiz::EskizVeri ev; ev.daireEkle(0, 0, 3.0); std::vector k; FIKO_KONTROL(sketchKontur2d(ev, k)); FIKO_KONTROL(k.size() == 1 && k[0].size() == 1); FIKO_KONTROL(k[0][0].tip == geometri::ProfilEgri2d::Tip::Cember); FIKO_YAKIN(k[0][0].yaricap, 3.0, 1e-9); } // KYA ad-çözme (kimlikMetniSec parse'ı) — boşluk/büyük-küçük harf toleransı + geçersiz reddi. FIKO_TEST(kya_ad_coz) { char tip = 0; u64 kid = 0; FIKO_KONTROL(kyaAdCoz("F7", tip, kid) && tip == 'F' && kid == 7); FIKO_KONTROL(kyaAdCoz("Kutu.1:E12", tip, kid) && tip == 'E' && kid == 12); // gövde prefiksi kırpılır FIKO_KONTROL(kyaAdCoz(" v5 ", tip, kid) && tip == 'V' && kid == 5); // boşluk + küçük harf FIKO_KONTROL(kyaAdCoz("Pad.1:f99", tip, kid) && tip == 'F' && kid == 99); FIKO_KONTROL(!kyaAdCoz("", tip, kid)); // boş FIKO_KONTROL(!kyaAdCoz("F", tip, kid)); // sayı yok FIKO_KONTROL(!kyaAdCoz("F0", tip, kid)); // kid 0 geçersiz FIKO_KONTROL(!kyaAdCoz("X7", tip, kid)); // geçersiz tip FIKO_KONTROL(!kyaAdCoz("F7x", tip, kid)); // sondaki çöp reddedilir (stoull olsa kabul ederdi) FIKO_KONTROL(!kyaAdCoz("F 7", tip, kid)); // ortada boşluk → rakam değil } // KYA format↔parse round-trip: kimlikMetni'nin ürettiği ad (kyaAdBicimle) kyaAdCoz ile geri // çözülebilmeli (kopyala-yapıştır iş akışı invariant'ı — toolbar'dan kopyala → aramaya yapıştır). FIKO_TEST(kya_ad_roundtrip) { for (char tip : {'F', 'E', 'V'}) { for (u64 kid : {1ull, 7ull, 12345ull, 999999ull}) { const std::string s = kyaAdBicimle(tip, kid, "Kutu.1"); char t2 = 0; u64 k2 = 0; FIKO_KONTROL(kyaAdCoz(s, t2, k2)); FIKO_KONTROL(t2 == tip && k2 == kid); // biçimlenen ad birebir geri çözülür } } // Gövde adı boşsa baştaki ":" olmadan biçimlenir ("E42"), yine çözülür (prefiks kozmetik). char t = 0; u64 k = 0; FIKO_KONTROL(kyaAdBicimle('E', 42, "") == "E42"); // adsız → temiz (":E42" değil) FIKO_KONTROL(kyaAdBicimle('F', 7, "Kutu.1") == "Kutu.1:F7"); FIKO_KONTROL(kyaAdCoz(kyaAdBicimle('E', 42, ""), t, k) && t == 'E' && k == 42); }