#include "fiko/sahne/sahne_islem.hpp" #include "fiko/cekirdek/cekirdek.hpp" #include "fiko/cekirdek/olay.hpp" #include "fiko/sahne/secim_sistemi.hpp" namespace fiko { // ---- EkleIslem ---- void EkleIslem::uygula(Dunya&, OlayGunlugu&) { if (!uygulandi_) { Dugum& yeni = sahne_.ekle(tip_); pusula_ = sahne_.anlik(yeni.kimlik); uygulandi_ = true; } else { sahne_.diril(pusula_); // redo: ayni kimlikle geri getir } } void EkleIslem::geriAl(Dunya&, OlayGunlugu&) { if (pusula_.kimlik) sahne_.sil(pusula_.kimlik); } // ---- SilIslem ---- void SilIslem::uygula(Dunya&, OlayGunlugu&) { pusulalar_.clear(); pusulalar_.reserve(kimlikler_.size()); for (const u32 k : kimlikler_) { DugumPusula p = sahne_.anlik(k); if (p.kimlik) { pusulalar_.push_back(std::move(p)); sahne_.sil(k); } } } void SilIslem::geriAl(Dunya&, OlayGunlugu&) { for (const auto& p : pusulalar_) sahne_.diril(p); } // ---- BooleanIslem ---- void BooleanIslem::uygula(Dunya&, OlayGunlugu&) { const auto govdeler = sahne_.seciliGovdeler(); if (govdeler.size() == 2) { operandA_ = sahne_.anlik(govdeler[0]); operandB_ = sahne_.anlik(govdeler[1]); } const u32 yeniKimlik = sahne_.booleanUygula(islem_); sonuc_ = yeniKimlik ? sahne_.anlik(yeniKimlik) : DugumPusula{}; } void BooleanIslem::geriAl(Dunya&, OlayGunlugu&) { if (sonuc_.kimlik) sahne_.sil(sonuc_.kimlik); if (operandA_.kimlik) sahne_.diril(operandA_); if (operandB_.kimlik) sahne_.diril(operandB_); } // ---- DuzenleIslem ---- namespace { inline bool esit(const Vec3f& a, const Vec3f& b) { return a.x == b.x && a.y == b.y && a.z == b.z; } inline bool esit(const Vec3d& a, const Vec3d& b) { return a.x == b.x && a.y == b.y && a.z == b.z; } inline bool esit(const Quatd& a, const Quatd& b) { return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; } inline bool esit(const Donusumd& a, const Donusumd& b) { return esit(a.konum, b.konum) && esit(a.yonelim, b.yonelim) && esit(a.olcek, b.olcek); } } // namespace void DuzenleIslem::pusulaUygula(const DugumPusula& p, OlayGunlugu& gunluk) { Dugum* d = sahne_.bul(p.kimlik); if (!d) return; const bool renkDegisti = !esit(d->renk, p.renk); const bool geoDegisti = d->p1 != p.p1 || d->p2 != p.p2 || d->p3 != p.p3 || d->aciZDerece != p.aciZDerece || renkDegisti || d->brep != p.brep; const bool donusumDegisti = !esit(d->donusum, p.donusum); const bool gorunurDegisti = d->gorunur != p.gorunur; // Öğe (yüz/kenar/nokta) görsel özellikleri değişti mi → mesh yeniden renklenmeli. const bool ozDegisti = d->yuzOz != p.yuzOz || d->kenarOz != p.kenarOz || d->noktaOz != p.noktaOz || d->yuzVars != p.yuzVars || d->kenarVars != p.kenarVars || d->noktaVars != p.noktaVars; d->ad = p.ad; d->gorunur = p.gorunur; d->p1 = p.p1; d->p2 = p.p2; d->p3 = p.p3; d->aciZDerece = p.aciZDerece; d->renk = p.renk; d->donusum = p.donusum; d->brep = p.brep; d->yuzOz = p.yuzOz; d->kenarOz = p.kenarOz; d->noktaOz = p.noktaOz; d->yuzVars = p.yuzVars; d->kenarVars = p.kenarVars; d->noktaVars = p.noktaVars; // G?VDE RENK SENKRON: yuzOz override renklerini BrepGovde::yuzRenkleri() ile // d??a aktar?m (STEP) ve seriizleme i?in GOVDEYE yaz. G?vde brep->gecerliMi() // kontrol? sonras?, yuzRenkleri boyutu face ordinal say?s?na e?it olmal?. if (d->brep && d->brep->gecerliMi() && !p.yuzOz.empty()) { const u32 nf = d->brep->yuzSayisi(); // toplam y?z say?s? std::vector yr(nf, d->renk); // taban: g?vde rengi for (const auto& kv : p.yuzOz) { u32 ord = kv.first; // face ordinal (1-tabanl?) if (ord >= 1 && ord <= nf) yr[ord - 1] = kv.second.renk; } d->brep->yuzRenkleriAta(std::move(yr)); } // Geometri değişti → yenidenInsa (mesh yeniden üçgenlenir). SALT öğe-özellik değişimi // (renk/alfa/görünür/malzeme) → YERİNDE ogeRenkYenile: yenidenInsa ithal gövdeyi yeniden // üçgenler → yüz ordinalleri (altKimlik) değişir → yuzOz eşlemesi bozulur (renk karışır/ // kaybolur). ogeRenkYenile ordinal-sabit, silinen override'ı tabana döndürür. if (geoDegisti) sahne_.yenidenInsa(*d); else if (ozDegisti) sahne_.ogeRenkYenile(*d); if (donusumDegisti) gunluk.yayinla(DonusumDegisti{p.kimlik}); if (gorunurDegisti) gunluk.yayinla(GorunurlukDegisti{p.kimlik, p.gorunur}); if (renkDegisti) gunluk.yayinla(RenkDegisti{p.kimlik}); } void DuzenleIslem::uygula(Dunya&, OlayGunlugu& gunluk) { if (ilk_) { ilk_ = false; return; } pusulaUygula(yeni_, gunluk); } void DuzenleIslem::geriAl(Dunya&, OlayGunlugu& gunluk) { pusulaUygula(eski_, gunluk); } // ---- HiyerarsiTasiIslem (ürün ağacı sürükle-bırak) ---- void HiyerarsiTasiIslem::uygula(Dunya& dunya, OlayGunlugu& gunluk) { for (const Kayit& k : kayitlar_) dunya.ekle(k.varlik, HiyerarsiBilesen{k.yeniUst, k.yeniSira}); gunluk.yayinla(HiyerarsiDegisti{0}); // toplu → ağaç tümden yeniden kurulur } void HiyerarsiTasiIslem::geriAl(Dunya& dunya, OlayGunlugu& gunluk) { for (const Kayit& k : kayitlar_) dunya.ekle(k.varlik, HiyerarsiBilesen{k.eskiUst, k.eskiSira}); gunluk.yayinla(HiyerarsiDegisti{0}); } // ---- DonusumIslem ---- void DonusumIslem::uygula(Dunya&, OlayGunlugu& gunluk) { if (Dugum* d = sahne_.bul(kimlik_)) { d->donusum = yeni_; gunluk.yayinla(DonusumDegisti{kimlik_}); } } void DonusumIslem::geriAl(Dunya&, OlayGunlugu& gunluk) { if (Dugum* d = sahne_.bul(kimlik_)) { d->donusum = eski_; gunluk.yayinla(DonusumDegisti{kimlik_}); } } void PaftaDuzenIslem::uygula(Dunya& d, OlayGunlugu& g) { if (pafta::Pafta* pv = paftaVerisi(d, pafta_)) { *pv = sonra_; g.yayinla(HiyerarsiDegisti{(u32)pafta_}, ad_); } } void PaftaDuzenIslem::geriAl(Dunya& d, OlayGunlugu& g) { if (pafta::Pafta* pv = paftaVerisi(d, pafta_)) { *pv = once_; g.yayinla(HiyerarsiDegisti{(u32)pafta_}, ad_); } } void PmiDuzenIslem::yaz(const pmi::PmiOge& kaynak) { if (!sistem_) return; if (pmi::PmiOge* o = sistem_->defter().bul(pmiKimlik_)) { const u32 s = o->surum; *o = kaynak; o->surum = s + 1; // metin önbelleği tazelensin (kopyadan gelen bayat sürümü ezme) } } void PmiDuzenIslem::uygula(Dunya&, OlayGunlugu& g) { yaz(sonra_); g.yayinla(PmiDegisti{pmiKimlik_}, ad_); } void PmiDuzenIslem::geriAl(Dunya&, OlayGunlugu& g) { yaz(once_); g.yayinla(PmiDegisti{pmiKimlik_}, ad_); } void PmiSilIslem::uygula(Dunya&, OlayGunlugu& g) { if (!sistem_) return; if (const pmi::PmiOge* o = sistem_->defter().bul(pmiKimlik_)) ogeKopya_ = *o; pusula_ = sahne_.anlik(dugumKimlik_); sahne_.sil(dugumKimlik_); sistem_->defter().sil(pmiKimlik_); g.yayinla(PmiSilindi{pmiKimlik_}, "PMI"); } void PmiSilIslem::geriAl(Dunya&, OlayGunlugu& g) { if (!sistem_) return; sistem_->defter().ekle(ogeKopya_); // kimlik korunur (ekle sonrakiKimlik'i ileri iter) if (pusula_.kimlik) sahne_.diril(pusula_); g.yayinla(PmiEklendi{pmiKimlik_}, "PMI"); } // ---- secimTiklaKaydet ---- void secimTiklaKaydet(Cekirdek& cekirdek, Sahne& sahne, SecimSistemi& secimSis, bool coklu) { const std::vector once = sahne.secililer(); secimSis.tikla(coklu); std::vector sonra = sahne.secililer(); if (sonra != once) cekirdek.uygula(std::make_unique(sahne, once, std::move(sonra))); } } // namespace fiko