#include "com/model/sahne_modeli.hpp" namespace fikatia { namespace { _variant_t vt(const std::wstring& s) { return _variant_t(s.c_str()); } bool boolOku(const FikomNesne& n, const wchar_t* ad) { _variant_t v = n.ozellik(ad); v.ChangeType(VT_BOOL); return v.boolVal != VARIANT_FALSE; } double dblOku(const FikomNesne& n, const wchar_t* ad) { _variant_t v = n.ozellik(ad); v.ChangeType(VT_R8); return v.dblVal; } double dblYap(_variant_t& v) { v.ChangeType(VT_R8); return v.dblVal; } FikomNesne nesneYap(_variant_t v) { return varyantNesne(v); } // CATIA CATSafeArrayVariant karsiligi: VT_VARIANT SAFEARRAY'i BYREF gecirilir ki // out-of-proc marshaling Get* cagrilarinda yazilan degerleri geri tasisin // (Python portu ayni isi VBScript eval ile yapiyordu). class SafeDizi { public: explicit SafeDizi(ULONG boyut) { SAFEARRAYBOUND sinir{boyut, 0}; sa_ = SafeArrayCreate(VT_VARIANT, 1, &sinir); if (!sa_) throw FikomHata("SAFEARRAY olusturulamadi", 0); } ~SafeDizi() { if (sa_) SafeArrayDestroy(sa_); } SafeDizi(const SafeDizi&) = delete; SafeDizi& operator=(const SafeDizi&) = delete; void yaz(LONG indeks, double deger) { _variant_t e(deger); SafeArrayPutElement(sa_, &indeks, &e); } double oku(LONG indeks) const { _variant_t e; SafeArrayGetElement(sa_, &indeks, &e); return dblYap(e); } std::wstring metinOku(LONG indeks) const { _variant_t e; SafeArrayGetElement(sa_, &indeks, &e); if (e.vt == VT_EMPTY || e.vt == VT_NULL) return {}; e.ChangeType(VT_BSTR); return e.bstrVal ? std::wstring(e.bstrVal) : std::wstring(); } _variant_t byref() { VARIANT v; VariantInit(&v); v.vt = VT_ARRAY | VT_VARIANT | VT_BYREF; v.pparray = &sa_; return _variant_t(v); // VT_BYREF kopyasi sig — sahiplik SafeDizi'de kalir } private: SAFEARRAY* sa_ = nullptr; }; // Skaler out-parametre (GetPick/GetRealColor...): VT_BYREF|VT_I4 sarici. struct ByrefSayi { long deger = 0; _variant_t v() { VARIANT t; VariantInit(&t); t.vt = VT_BYREF | VT_I4; t.plVal = °er; return _variant_t(t); } }; std::array vektor3Oku(FikomNesne& n, const wchar_t* ad) { SafeDizi d(3); n.metod(ad, {d.byref()}); return {d.oku(0), d.oku(1), d.oku(2)}; } void vektor3Yaz(FikomNesne& n, const wchar_t* ad, const std::array& deger) { SafeDizi d(3); for (LONG i = 0; i < 3; ++i) d.yaz(i, deger[(size_t)i]); n.metod(ad, {d.byref()}); } // Nesne-degerli ozellik atamasi PROPERTYPUTREF ister (FikomNesne::ozellikAyarla yalniz // PROPERTYPUT yapar; fikom_nesne.hpp'ye dokunmama kisiti nedeniyle burada ham Invoke). void nesneAyarla(FikomNesne& hedef, const wchar_t* ad, const FikomNesne& deger) { IDispatch* p = hedef.ham(); if (!p) throw FikomHata("Bos COM nesnesi uzerinde nesne atamasi", 0); DISPID kimlik = DISPID_UNKNOWN; LPOLESTR adPtr = const_cast(ad); HRESULT hr = p->GetIDsOfNames(IID_NULL, &adPtr, 1, LOCALE_USER_DEFAULT, &kimlik); if (FAILED(hr)) throw FikomHata("CATIA ozellik adi bulunamadi (nesne atama)", (long)hr); VARIANT v; VariantInit(&v); v.vt = VT_DISPATCH; v.pdispVal = deger.ham(); DISPID putKimlik = DISPID_PROPERTYPUT; DISPPARAMS dp{&v, &putKimlik, 1, 1}; EXCEPINFO ei{}; UINT hataArg = 0; hr = p->Invoke(kimlik, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF | DISPATCH_PROPERTYPUT, &dp, nullptr, &ei, &hataArg); if (FAILED(hr)) { if (ei.bstrDescription) SysFreeString(ei.bstrDescription); if (ei.bstrSource) SysFreeString(ei.bstrSource); if (ei.bstrHelpFile) SysFreeString(ei.bstrHelpFile); throw FikomHata("CATIA nesne atamasi basarisiz", (long)hr); } } } // namespace // ---- Birim ------------------------------------------------------------------- double Birim::cevirMKSden(double deger) { _variant_t v = com_.metod(L"ConvertFromMKS", {_variant_t(deger)}); return dblYap(v); } double Birim::cevirBirimden(double deger) { _variant_t v = com_.metod(L"ConvertFromStorageUnit", {_variant_t(deger)}); return dblYap(v); } double Birim::cevirMKSye(double deger) { _variant_t v = com_.metod(L"ConvertToMKS", {_variant_t(deger)}); return dblYap(v); } double Birim::cevirBirime(double deger) { _variant_t v = com_.metod(L"ConvertToStorageUnit", {_variant_t(deger)}); return dblYap(v); } // ---- Referans ------------------------------------------------------------------ Referans Referans::iliskilendir(const FikomNesne& referans) { return Referans(nesneYap(com_.metod(L"ComposeWith", {_variant_t(referans.ham(), true)}))); } // ---- GorunumAyarlari ----------------------------------------------------------- long GorunumAyarlari::katman() { ByrefSayi tip, katmanNo; com_.metod(L"GetLayer", {tip.v(), katmanNo.v()}); return tip.deger == 0 ? katmanNo.deger : -1; } void GorunumAyarlari::katmanAyarla(long deger) { com_.metod(L"SetLayer", {_variant_t(0L), _variant_t(deger)}); } bool GorunumAyarlari::secilebilir() { ByrefSayi mod; com_.metod(L"GetPick", {mod.v()}); return mod.deger == 0; // catVisPropertyPickAttr=0 → secilebilir } void GorunumAyarlari::secilebilirAyarla(bool v) { com_.metod(L"SetPick", {_variant_t(v ? 0L : 1L)}); } std::array GorunumAyarlari::renkRGB() { ByrefSayi r, g, b; com_.metod(L"GetRealColor", {r.v(), g.v(), b.v()}); return {r.deger, g.deger, b.deger}; } void GorunumAyarlari::renkRGBAyarla(long r, long g, long b, long kalitim) { com_.metod(L"SetRealColor", {_variant_t(r), _variant_t(g), _variant_t(b), _variant_t(kalitim)}); } bool GorunumAyarlari::gorunur() { ByrefSayi mod; com_.metod(L"GetShow", {mod.v()}); return mod.deger == 0; // catVisPropertyShowAttr=0 → gorunur } void GorunumAyarlari::gorunurAyarla(bool v) { com_.metod(L"SetShow", {_variant_t(v ? 0L : 1L)}); } long GorunumAyarlari::seffaflik() { ByrefSayi deger; com_.metod(L"GetRealOpacity", {deger.v()}); return deger.deger; } void GorunumAyarlari::seffaflikAyarla(long v) { com_.metod(L"SetRealOpacity", {_variant_t(v), _variant_t(1L)}); } long GorunumAyarlari::cizgiTipiGercek() { ByrefSayi deger; com_.metod(L"GetRealLineType", {deger.v()}); return deger.deger; } void GorunumAyarlari::cizgiTipiGercekAyarla(long v) { com_.metod(L"SetRealLineType", {_variant_t(v), _variant_t(1L)}); } long GorunumAyarlari::cizgiTipiGenislik() { ByrefSayi deger; com_.metod(L"GetRealWidth", {deger.v()}); return deger.deger; } void GorunumAyarlari::cizgiTipiGenislikAyarla(long v) { com_.metod(L"SetRealWidth", {_variant_t(v), _variant_t(1L)}); } long GorunumAyarlari::sembolTipi() { ByrefSayi deger; com_.metod(L"GetSymbolType", {deger.v()}); return deger.deger; } void GorunumAyarlari::sembolTipiAyarla(long v) { com_.metod(L"SetSymbolType", {_variant_t(v)}); } // ---- Paylasilan(lar) ----------------------------------------------------------- void Paylasilan::degistir(const FikomNesne& paylasilan) { com_.metod(L"Relay", {_variant_t(paylasilan.ham(), true)}); } Paylasilan Paylasilanlar::ekle(const std::wstring& isim) { return Paylasilan(nesneYap(com_.metod(L"Add", {vt(isim)}))); } Paylasilan Paylasilanlar::eleman(const std::wstring& ad) { return Paylasilan(nesneYap(com_.metod(L"Item", {vt(ad)}))); } void Paylasilanlar::sil(long indeks) { com_.metod(L"Remove", {_variant_t(indeks + 1)}); } void Paylasilanlar::sil(const std::wstring& ad) { com_.metod(L"Remove", {vt(ad)}); } void Paylasilanlar::direktAyarla(const std::wstring& isim, const FikomNesne& referans) { com_.metod(L"SetDirect", {vt(isim), _variant_t(referans.ham(), true)}); } void Paylasilanlar::degistir(const std::wstring& isim, const std::wstring& paylasimIsmi, const FikomNesne& product) { com_.metod(L"SetRelay", {vt(isim), vt(paylasimIsmi), _variant_t(product.ham(), true)}); } // ---- SistemKonfigurasyonu ------------------------------------------------------ std::vector SistemKonfigurasyonu::urunListesi() { const long n = urunSayisi(); if (n <= 0) return {}; SafeDizi d((ULONG)n); com_.metod(L"GetProductNames", {d.byref()}); std::vector liste; liste.reserve((size_t)n); for (LONG i = 0; i < n; ++i) liste.push_back(d.metinOku(i)); return liste; } bool SistemKonfigurasyonu::urunLisanslimi(const std::wstring& urun) { for (const std::wstring& ad : urunListesi()) if (ad == urun) return true; return false; } // ---- Hareket ------------------------------------------------------------------- void Hareket::uygula(const std::array& matris) { SafeDizi d(12); for (LONG i = 0; i < 12; ++i) d.yaz(i, matris[(size_t)i]); com_.metod(L"Apply", {d.byref()}); } // ---- GosterimNoktasi3d --------------------------------------------------------- double GosterimNoktasi3d::gorusAlani() const { return dblOku(com_, L"FieldOfView"); } double GosterimNoktasi3d::odakUzakligi() const { return dblOku(com_, L"FocusDistance"); } double GosterimNoktasi3d::yakinlastirma() const { return dblOku(com_, L"Zoom"); } std::array GosterimNoktasi3d::merkezNoktasi() { return vektor3Oku(com_, L"GetOrigin"); } void GosterimNoktasi3d::merkezNoktasiAyarla(const std::array& v) { vektor3Yaz(com_, L"PutOrigin", v); } std::array GosterimNoktasi3d::gormeYonu() { return vektor3Oku(com_, L"GetSightDirection"); } void GosterimNoktasi3d::gormeYonuAyarla(const std::array& v) { vektor3Yaz(com_, L"PutSightDirection", v); } std::array GosterimNoktasi3d::ustYon() { return vektor3Oku(com_, L"GetUpDirection"); } void GosterimNoktasi3d::ustYonAyarla(const std::array& v) { vektor3Yaz(com_, L"PutUpDirection", v); } // ---- Kamera(lar) ----------------------------------------------------------------- void Kamera::gosterimNoktasiAyarla(const GosterimNoktasi3d& v) { nesneAyarla(com_, L"ViewPoint3d", v.com()); } void Kamera::goster(Gosterim3d& gosterim) { gosterim.gosterimNoktasiAyarla(gosterimNoktasi3d()); gosterim.guncelle(); } std::wstring Kamera::resimDosyaya(Gosterim3d& gosterim, const std::wstring& dosya, ResimFormati format, const std::array& arkaPlan, bool agacGorunsun) { goster(gosterim); return gosterim.resimDosyaya(dosya, format, arkaPlan, agacGorunsun); } Kamera Kameralar::eleman(const std::wstring& ad) const { const long n = adet(); for (long i = 0; i < n; ++i) { Kamera k = eleman(i); if (k.ismi() == ad) return k; } return {}; } void Kameralar::sil(long indeks) { com_.metod(L"Remove", {_variant_t(indeks + 1)}); } void Kameralar::sil(const std::wstring& ad) { const long n = adet(); for (long i = 0; i < n; ++i) { if (eleman(i).ismi() == ad) { sil(i); return; } } } // ---- Gosterim3d ------------------------------------------------------------------ bool Gosterim3d::tamEkran() const { return boolOku(com_, L"FullScreen"); } double Gosterim3d::uzakLimit() const { return dblOku(com_, L"FarLimit"); } double Gosterim3d::yakinLimit() const { return dblOku(com_, L"NearLimit"); } bool Gosterim3d::sisliMod() const { return boolOku(com_, L"Foggy"); } double Gosterim3d::isikYogunlugu() const { return dblOku(com_, L"LightingIntensity"); } Kamera Gosterim3d::yeniKamera(const std::wstring& ismi) { Kamera yeni(nesneYap(com_.metod(L"NewCamera"))); if (!ismi.empty()) yeni.ismiAyarla(ismi); return yeni; } std::wstring Gosterim3d::resimDosyaya(const std::wstring& dosya, ResimFormati format, const std::array& arkaPlan, bool agacGorunsun) { FikomNesne uygulama = com_.nesne(L"Application"); if (!agacGorunsun) uygulama.metod(L"StartCommand", {vt(L"Specifications")}); const std::array eskiRenk = arkaPlanRengi(); arkaPlanRengiAyarla(arkaPlan); com_.metod(L"CaptureToFile", {_variant_t((long)format), vt(dosya)}); arkaPlanRengiAyarla(eskiRenk); if (!agacGorunsun) uygulama.metod(L"StartCommand", {vt(L"Specifications")}); return dosya; } std::array Gosterim3d::arkaPlanRengi() { return vektor3Oku(com_, L"GetBackgroundColor"); } void Gosterim3d::arkaPlanRengiAyarla(const std::array& rgb) { vektor3Yaz(com_, L"PutBackgroundColor", rgb); } void Gosterim3d::gosterimNoktasiAyarla(const GosterimNoktasi3d& v) { nesneAyarla(com_, L"ViewPoint3d", v.com()); } void Gosterim3d::dondur(const std::array& yon, double derece, bool guncellensin) { SafeDizi d(3); for (LONG i = 0; i < 3; ++i) d.yaz(i, yon[(size_t)i]); com_.metod(L"Rotate", {d.byref(), _variant_t(derece)}); if (guncellensin) guncelle(); } void Gosterim3d::gotur(const std::array& vektor, bool guncellensin) { SafeDizi d(3); for (LONG i = 0; i < 3; ++i) d.yaz(i, vektor[(size_t)i]); com_.metod(L"Translate", {d.byref()}); if (guncellensin) guncelle(); } // ---- Pencere(ler) ---------------------------------------------------------------- void Pencere::yazdirDosyaya(const std::wstring& dosya) { com_.metod(L"PrintToFile", {vt(dosya)}); } Pencere Pencere::yeniPencere() { return Pencere(nesneYap(com_.metod(L"NewWindow"))); } Pencere Pencereler::eleman(const std::wstring& ad) { return Pencere(nesneYap(com_.metod(L"Item", {vt(ad)}))); } // ---- Eksen(ler) ------------------------------------------------------------------ void Eksen::eksenDondurmeAcisiAyarla(const std::wstring& deger) { std::wstring v = deger; if (v.find(L"deg") == std::wstring::npos) v += L"deg"; eksenDondurmeAcisi().degeriStrAyarla(v); } void Eksen::eksenDondurmeAcisiAyarla(double derece) { eksenDondurmeAcisi().degeriStrAyarla(std::to_wstring(derece) + L"deg"); } void Eksen::eksenDondurmeReferansiAyarla(const Referans& v) { nesneAyarla(com_, L"AxisRotationReference", v.com()); } bool Eksen::gecerliEksen() const { return boolOku(com_, L"IsCurrent"); } void Eksen::merkezNoktasiAyarla(const Referans& v) { nesneAyarla(com_, L"OriginPoint", v.com()); } void Eksen::xYonuAyarla(const Referans& v) { nesneAyarla(com_, L"XAxisDirection", v.com()); } void Eksen::yYonuAyarla(const Referans& v) { nesneAyarla(com_, L"YAxisDirection", v.com()); } void Eksen::zYonuAyarla(const Referans& v) { nesneAyarla(com_, L"ZAxisDirection", v.com()); } std::array Eksen::eularAcilari() { // GetEulerAngles uc Angle nesnesini out-parametre dondurur: VT_BYREF|VT_VARIANT depolari. VARIANT depo[3]; for (VARIANT& d : depo) VariantInit(&d); { std::vector<_variant_t> args; args.reserve(3); for (VARIANT& d : depo) { VARIANT b; VariantInit(&b); b.vt = VT_BYREF | VT_VARIANT; b.pvarVal = &d; args.emplace_back(b); } com_.metod(L"GetEulerAngles", std::move(args)); } std::array sonuc; for (int i = 0; i < 3; ++i) { _variant_t sahipli(depo[i], false); // sahiplik devri: yikimda temizlenir sonuc[(size_t)i] = Parametre(varyantNesne(sahipli)); } return sonuc; } std::array Eksen::merkez() { return vektor3Oku(com_, L"GetOrigin"); } void Eksen::merkezAyarla(const std::array& v) { vektor3Yaz(com_, L"PutOrigin", v); } std::array Eksen::vektorXY() { SafeDizi dx(3), dy(3); com_.metod(L"GetVectors", {dx.byref(), dy.byref()}); return {dx.oku(0), dx.oku(1), dx.oku(2), dy.oku(0), dy.oku(1), dy.oku(2)}; } void Eksen::vektorXYAyarla(const std::array& v) { SafeDizi dx(3), dy(3); for (LONG i = 0; i < 3; ++i) { dx.yaz(i, v[(size_t)i]); dy.yaz(i, v[(size_t)i + 3]); } com_.metod(L"PutVectors", {dx.byref(), dy.byref()}); } std::array Eksen::x() { return vektor3Oku(com_, L"GetXAxis"); } void Eksen::xAyarla(const std::array& v) { vektor3Yaz(com_, L"PutXAxis", v); } std::array Eksen::y() { return vektor3Oku(com_, L"GetYAxis"); } void Eksen::yAyarla(const std::array& v) { vektor3Yaz(com_, L"PutYAxis", v); } std::array Eksen::z() { return vektor3Oku(com_, L"GetZAxis"); } void Eksen::zAyarla(const std::array& v) { vektor3Yaz(com_, L"PutZAxis", v); } Eksen Eksenler::ekle() { return Eksen(nesneYap(com_.metod(L"Add"))); } Eksen Eksenler::eleman(const std::wstring& ad) const { const long n = adet(); for (long i = 0; i < n; ++i) { Eksen e = eleman(i); if (e.ismi() == ad) return e; } return {}; } // ---- PPRProductlar --------------------------------------------------------------- Product PPRProductlar::ekle(const FikomNesne& product) { com_.metod(L"Add", {_variant_t(product.ham(), true)}); return eleman(adet() - 1); } } // namespace fikatia