// fiko.sahne.* + fiko.secim.* + fiko.olay.* Lua bağlama katmanı. // MakroMotor'un ilgili l_* static üyeleri burada tanımlanır (davranış değişikliği // SIFIR — bloklar makro_motor.cpp'den olduğu gibi taşındı). #include "fiko/betik/makro_motor.hpp" #include #include #include #include "fiko/cekirdek/cekirdek.hpp" #include "fiko/sahne/alan_secim.hpp" #include "fiko/sahne/sahne.hpp" #include "fiko/sahne/sahne_islem.hpp" #include "makro_ic.hpp" extern "C" { #include "lauxlib.h" #include "lua.h" } namespace fiko::betik { using makroic::olayIndeksi; namespace { bool primTip(const char* s, DugumTip& t) { if (std::strcmp(s, "kutu") == 0) t = DugumTip::Kutu; else if (std::strcmp(s, "silindir") == 0) t = DugumTip::Silindir; else if (std::strcmp(s, "kure") == 0) t = DugumTip::Kure; else if (std::strcmp(s, "koni") == 0) t = DugumTip::Koni; else return false; return true; } bool boolTip(const char* s, DugumTip& t) { if (std::strcmp(s, "birlesim") == 0) t = DugumTip::Birlesim; else if (std::strcmp(s, "cikarma") == 0) t = DugumTip::Cikarma; else if (std::strcmp(s, "kesisim") == 0) t = DugumTip::Kesisim; else return false; return true; } std::vector kimlikler(Sahne& s) { std::vector v; v.reserve(s.dugumler().size()); for (const Dugum& d : s.dugumler()) v.push_back(d.kimlik); return v; } u32 yeniKimlik(Sahne& s, const std::vector& once) { for (const Dugum& d : s.dugumler()) if (std::find(once.begin(), once.end(), d.kimlik) == once.end()) return d.kimlik; return 0; } } // namespace int MakroMotor::l_olayDinle(lua_State* L) { MakroMotor* m = kendisi(L); const char* ad = luaL_checkstring(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); const int idx = olayIndeksi(ad); if (idx < 0) { lua_pushnil(L); return 1; } lua_pushvalue(L, 2); m->dinleyiciler_[static_cast(idx)].push_back(luaL_ref(L, LUA_REGISTRYINDEX)); lua_pushboolean(L, 1); return 1; } int MakroMotor::l_sahneEkle(lua_State* L) { MakroMotor* m = kendisi(L); DugumTip tip; if (!primTip(luaL_checkstring(L, 1), tip)) { lua_pushnil(L); return 1; } const std::vector once = kimlikler(m->sahne_); m->cekirdek_.uygula(std::make_unique(m->sahne_, tip)); const u32 k = yeniKimlik(m->sahne_, once); if (k) lua_pushinteger(L, static_cast(k)); else lua_pushnil(L); return 1; } int MakroMotor::l_sahneSil(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); if (!m->sahne_.bul(k)) { lua_pushnil(L); return 1; } m->cekirdek_.uygula(std::make_unique(m->sahne_, std::vector{k})); lua_pushboolean(L, 1); return 1; } int MakroMotor::l_sahneDugumler(lua_State* L) { MakroMotor* m = kendisi(L); const std::vector& dugumler = m->sahne_.dugumler(); lua_createtable(L, static_cast(dugumler.size()), 0); int i = 1; for (const Dugum& d : dugumler) { lua_pushinteger(L, static_cast(d.kimlik)); lua_rawseti(L, -2, i++); } return 1; } int MakroMotor::l_sahneAd(lua_State* L) { MakroMotor* m = kendisi(L); const Dugum* d = m->sahne_.bul(static_cast(luaL_checkinteger(L, 1))); if (!d) lua_pushnil(L); else lua_pushlstring(L, d->ad.c_str(), d->ad.size()); return 1; } int MakroMotor::l_sahneAdAyarla(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); Dugum* d = m->sahne_.bul(k); if (!d) { lua_pushnil(L); return 1; } d->ad = luaL_checkstring(L, 2); if (AdBilesen* a = m->cekirdek_.dunya().bul(k)) a->ad = d->ad; lua_pushboolean(L, 1); return 1; } int MakroMotor::l_sahneKonum(lua_State* L) { MakroMotor* m = kendisi(L); const Dugum* d = m->sahne_.bul(static_cast(luaL_checkinteger(L, 1))); if (!d) { lua_pushnil(L); return 1; } lua_pushnumber(L, static_cast(d->donusum.konum.x)); lua_pushnumber(L, static_cast(d->donusum.konum.y)); lua_pushnumber(L, static_cast(d->donusum.konum.z)); return 3; } int MakroMotor::l_sahneKonumAyarla(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); Dugum* d = m->sahne_.bul(k); if (!d) { lua_pushnil(L); return 1; } d->donusum.konum = {luaL_checknumber(L, 2), luaL_checknumber(L, 3), luaL_checknumber(L, 4)}; if (DonusumBilesen* b = m->cekirdek_.dunya().bul(k)) b->donusum = d->donusum; m->cekirdek_.olaylar().yayinla(DonusumDegisti{k}, d->ad.c_str()); lua_pushboolean(L, 1); return 1; } int MakroMotor::l_sahneRenkAyarla(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); Dugum* d = m->sahne_.bul(k); if (!d) { lua_pushnil(L); return 1; } d->renk = {static_cast(luaL_checknumber(L, 2)), static_cast(luaL_checknumber(L, 3)), static_cast(luaL_checknumber(L, 4))}; if (RenkBilesen* b = m->cekirdek_.dunya().bul(k)) b->renk = d->renk; // GÖVDE TABAN RENGİ mesh'e de işlensin. `d->renk` yalnız bir sonraki `yenidenInsa`da // (ucgenle) mesh'e geçer; render ise `yuzOz` override → yoksa `cpuRenkBaz` okur // (bkz. Sahne::ogeRenkYenile). Bu iki satır olmadan Lua'dan verilen renk EKRANDA // HİÇ GÖRÜNMÜYORDU (ölçüldü 07-21: MCP ile modellenen kumpas tek renk çıktı). // Yüz bazlı override'lar (yuzOz) korunur — ogeRenkYenile onları üstte tutar. if (!d->cpuKonum.empty()) { d->cpuRenkBaz.assign(d->cpuKonum.size(), d->renk); m->sahne_.ogeRenkYenile(*d); } m->cekirdek_.olaylar().yayinla(RenkDegisti{k}, d->ad.c_str()); lua_pushboolean(L, 1); return 1; } int MakroMotor::l_sahneGorunurAyarla(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); Dugum* d = m->sahne_.bul(k); if (!d) { lua_pushnil(L); return 1; } d->gorunur = lua_toboolean(L, 2) != 0; if (GorunurBilesen* b = m->cekirdek_.dunya().bul(k)) b->gorunur = d->gorunur; m->cekirdek_.olaylar().yayinla(GorunurlukDegisti{k, d->gorunur}, d->ad.c_str()); lua_pushboolean(L, 1); return 1; } int MakroMotor::l_sahneParametreAyarla(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); Dugum* d = m->sahne_.bul(k); if (!d) { lua_pushnil(L); return 1; } d->p1 = static_cast(luaL_optnumber(L, 2, static_cast(d->p1))); d->p2 = static_cast(luaL_optnumber(L, 3, static_cast(d->p2))); d->p3 = static_cast(luaL_optnumber(L, 4, static_cast(d->p3))); m->sahne_.yenidenInsa(*d); lua_pushboolean(L, 1); return 1; } int MakroMotor::l_sahneBoolean(lua_State* L) { MakroMotor* m = kendisi(L); DugumTip tip; if (!boolTip(luaL_checkstring(L, 1), tip) || m->sahne_.seciliGovdeler().size() != 2) { lua_pushnil(L); return 1; } const std::vector once = kimlikler(m->sahne_); m->cekirdek_.uygula(std::make_unique(m->sahne_, tip)); const u32 k = yeniKimlik(m->sahne_, once); if (k) lua_pushinteger(L, static_cast(k)); else lua_pushnil(L); return 1; } int MakroMotor::l_sahneStepIceAktar(lua_State* L) { MakroMotor* m = kendisi(L); lua_pushinteger(L, m->sahne_.stepIceAktar(luaL_checkstring(L, 1))); return 1; } int MakroMotor::l_sahneStepDisaAktar(lua_State* L) { MakroMotor* m = kendisi(L); const bool ok = m->sahne_.stepDisaAktar(luaL_checkstring(L, 1), lua_toboolean(L, 2) != 0); lua_pushboolean(L, ok ? 1 : 0); return 1; } // fiko.sahne.alanSec(tip): aktif alan-seçim trap tipini ayarla (mod başlatma). // tip: "dikdortgen"|"kesen"|"poligon"|"firca"|"disicinde"|"diskesen" veya 0-5. // Trap fiili çizimi kullanıcı sol-drag'iyle başlar; bu yalnız aktif tipi seçer // (CATIA dışlayıcı mod deseni). alan bağlı değilse nil döner. int MakroMotor::l_sahneAlanSec(lua_State* L) { MakroMotor* m = kendisi(L); if (!m->alan_) { lua_pushnil(L); return 1; } TrapTip tip = TrapTip::Dikdortgen; if (lua_type(L, 1) == LUA_TNUMBER) { const int i = (int)luaL_checkinteger(L, 1); if (i >= 0 && i <= 5) tip = (TrapTip)i; } else { const std::string s = luaL_checkstring(L, 1); if (s == "kesen") tip = TrapTip::KesenDikdortgen; else if (s == "poligon") tip = TrapTip::Poligon; else if (s == "firca") tip = TrapTip::FircaIzi; else if (s == "disicinde") tip = TrapTip::DisRadikdortgen; else if (s == "diskesen") tip = TrapTip::DisKesen; else tip = TrapTip::Dikdortgen; } m->alan_->tip = tip; lua_pushstring(L, trapAdi(tip)); return 1; } int MakroMotor::l_secimSecililer(lua_State* L) { MakroMotor* m = kendisi(L); const std::vector govdeler = m->sahne_.seciliGovdeler(); lua_createtable(L, static_cast(govdeler.size()), 0); int i = 1; for (u32 g : govdeler) { lua_pushinteger(L, static_cast(g)); lua_rawseti(L, -2, i++); } return 1; } int MakroMotor::l_secimTemizle(lua_State* L) { MakroMotor* m = kendisi(L); m->sahne_.secimTemizle(); m->cekirdek_.olaylar().yayinla(SecimDegisti{}); return 0; } int MakroMotor::l_secimSec(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); // K6: opsiyonel 2. arg = alt ordinal (yüz/kenar/nokta) — UI paritesi. 0 = gövde. const u32 alt = static_cast(luaL_optinteger(L, 2, 0)); if (!m->sahne_.bul(k)) { lua_pushnil(L); return 1; } m->sahne_.sec({k, alt}, true); lua_pushboolean(L, 1); return 1; } int MakroMotor::l_secimKip(lua_State* L) { MakroMotor* m = kendisi(L); const char* s = luaL_checkstring(L, 1); SecimKip kip; if (std::strcmp(s, "govde") == 0) kip = SecimKip::Govde; else if (std::strcmp(s, "yuz") == 0) kip = SecimKip::Yuz; else if (std::strcmp(s, "kenar") == 0) kip = SecimKip::Kenar; else if (std::strcmp(s, "nokta") == 0) kip = SecimKip::Nokta; else { lua_pushnil(L); return 1; } m->sahne_.kipAyarla(kip); lua_pushboolean(L, 1); return 1; } // KYA kalıcı kimlik — betik erişimi (anayasa: her sistem makro erişilebilir). // fiko.secim.kimlik(govde[, alt]) → "Kutu.1:F7" | nil ; fiko.secim.kimlikSec("F7") → true|false. int MakroMotor::l_secimKimlik(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); const u32 alt = static_cast(luaL_optinteger(L, 2, 0)); const std::string ad = m->sahne_.kimlikMetni({k, alt}); // kip'e göre F/E/V if (ad.empty()) lua_pushnil(L); else lua_pushstring(L, ad.c_str()); return 1; } int MakroMotor::l_secimKimlikSec(lua_State* L) { MakroMotor* m = kendisi(L); const char* ad = luaL_checkstring(L, 1); lua_pushboolean(L, m->sahne_.kimlikMetniSec(ad) ? 1 : 0); return 1; } // fiko.secim.kimlikListe(govde) → { [ordinal] = kid, ... } (yüz KYA etiketleri). Makrolar gövdenin // yüzlerini kalıcı kimlikleriyle gezebilir (toplu işlem/betik). Ayar açık + etiketsizse etiketler. int MakroMotor::l_secimKimlikListe(lua_State* L) { MakroMotor* m = kendisi(L); const u32 k = static_cast(luaL_checkinteger(L, 1)); Dugum* d = m->sahne_.bul(k); if (!d || !d->brep) { lua_pushnil(L); return 1; } if (geometri::kaliciKimlikAcikMi() && !d->brep->kimlikliMi()) d->brep->kimlikleriBaslat(); const std::vector& kidler = d->brep->yuzKimlikleri(); lua_createtable(L, static_cast(kidler.size()), 0); for (std::size_t i = 0; i < kidler.size(); ++i) { lua_pushinteger(L, static_cast(kidler[i])); lua_rawseti(L, -2, static_cast(i + 1)); // ordinal (1-tabanlı) → kid } return 1; } } // namespace fiko::betik