#include "referans_penceresi.hpp" #include #include #include "fiko/sahne/sahne.hpp" #include "fiko/ui/pencere_cerceve.hpp" #include "fiko/ui/tema.hpp" #include "imgui.h" namespace fiko { namespace { // ---- Pencere durumu (UI-only; kalıcı statik) ---- bool g_acik = false; bool g_ustte = false; int g_tur = 0; // 0=Nokta, 1=Çizgi, 2=Düzlem int g_odakIste = -1; // referansPencereAc → o sekmeye zıpla (bir kare) // Giriş alanları (her tür/alt-mod kendi tamponunu tutar → mod değişince kaybolmaz). float g_nokta[3] = {0, 0, 0}; int g_cizgiMod = 0; // 0=İki Nokta, 1=Nokta+Yön float g_cizP1[3] = {0, 0, 0}; float g_cizP2[3] = {10, 0, 0}; float g_cizYon[3] = {1, 0, 0}; float g_cizUzun = 10.0f; int g_duzMod = 0; // 0=Ofset, 1=3 Nokta, 2=Nokta+Normal int g_duzTaban = 0; // ofset taban düzlemi seçimi (0..2 origin, sonra ref düzlemler) float g_duzMesafe = 10.0f; float g_duzP1[3] = {0, 0, 0}; float g_duzP2[3] = {10, 0, 0}; float g_duzP3[3] = {0, 10, 0}; float g_duzNokta[3] = {0, 0, 0}; float g_duzNormal[3] = {0, 0, 1}; bool g_duzHemenSketch = false; // düzlem oluşunca sketch aç // Ofset taban düzlemi adayı: origin XY/YZ/ZX + sahnedeki referans DÜZLEM düğümleri. struct TabanDuzlem { std::string ad; Vec3d konum; Vec3d normal; u32 kaynak = 0; // gerçek DÜZLEM düğümü Varlik (0 = origin literali → parametrik değil) }; std::vector tabanDuzlemleriTopla(Sahne& sahne) { std::vector liste; liste.push_back({"XY (Origin)", {0, 0, 0}, {0, 0, 1}, 0}); liste.push_back({"YZ (Origin)", {0, 0, 0}, {1, 0, 0}, 0}); liste.push_back({"ZX (Origin)", {0, 0, 0}, {0, 1, 0}, 0}); for (const Dugum& d : sahne.dugumler()) { if (d.tip != DugumTip::Duzlem) continue; // Referans düzlemin dünya normali = yerel +Z döndürülmüş. const Vec3d n = d.donusum.yonelim.dondur({0, 0, 1}); liste.push_back({d.ad.empty() ? "Düzlem" : d.ad, d.donusum.konum, n, d.kimlik}); } return liste; } Vec3d v3(const float a[3]) { return {(f64)a[0], (f64)a[1], (f64)a[2]}; } } // namespace void referansPencereAc(int baslangicTur) { g_acik = true; g_odakIste = (baslangicTur >= 0 && baslangicTur <= 2) ? baslangicTur : 0; } void referansPencereCiz(Sahne& sahne, const std::function& sketchGir, const std::function& bilgiVer) { if (!g_acik) return; const ImVec4 CYAN = ui::tema().vurgu; const ImVec4 SOLUK = ui::tema().metinSoluk; const ImVec4 YESIL = ui::tema().basari; const auto bilgi = [&](std::string m) { if (bilgiVer) bilgiVer(std::move(m)); }; ui::Pencere pen{"Referans Öğe###referans_pencere", &g_acik, {.boyut = {360, 0}, .pinDurum = &g_ustte}}; if (!pen) return; if (ImGui::BeginTabBar("##refTur")) { auto sekmeBayrak = [&](int t) { return (g_odakIste == t) ? ImGuiTabItemFlags_SetSelected : 0; }; // ---- NOKTA ---- if (ImGui::BeginTabItem("• Nokta", nullptr, sekmeBayrak(0))) { g_tur = 0; ImGui::TextColored(SOLUK, "Koordinatla referans nokta (gp_Pnt)."); ImGui::InputFloat3("X / Y / Z", g_nokta); if (ImGui::Button("Oluştur", {-1, 0})) { const Varlik v = sahne.referansNoktaEkle(v3(g_nokta)); if (v != VARLIK_YOK) bilgi("Referans nokta oluşturuldu"); } ImGui::EndTabItem(); } // ---- ÇİZGİ ---- if (ImGui::BeginTabItem("╱ Çizgi", nullptr, sekmeBayrak(1))) { g_tur = 1; ImGui::RadioButton("İki Nokta", &g_cizgiMod, 0); ImGui::SameLine(); ImGui::RadioButton("Nokta + Yön", &g_cizgiMod, 1); ImGui::Separator(); if (g_cizgiMod == 0) { ImGui::InputFloat3("Başlangıç", g_cizP1); ImGui::InputFloat3("Bitiş", g_cizP2); if (ImGui::Button("Oluştur", {-1, 0})) { const Varlik v = sahne.referansCizgiEkle(v3(g_cizP1), v3(g_cizP2)); if (v != VARLIK_YOK) bilgi("Referans çizgi oluşturuldu"); else bilgi("Çizgi oluşturulamadı: başlangıç ve bitiş aynı"); } } else { ImGui::InputFloat3("Nokta", g_cizP1); ImGui::InputFloat3("Yön", g_cizYon); ImGui::InputFloat("Uzunluk", &g_cizUzun); if (ImGui::Button("Oluştur", {-1, 0})) { const Vec3d p0 = v3(g_cizP1); const Vec3d yon = v3(g_cizYon); if (yon.uzunluk() < 1e-9) { bilgi("Çizgi oluşturulamadı: yön sıfır"); } else { const Vec3d p1 = p0 + yon.birim() * (f64)g_cizUzun; const Varlik v = sahne.referansCizgiEkle(p0, p1); if (v != VARLIK_YOK) bilgi("Referans çizgi oluşturuldu"); } } } ImGui::EndTabItem(); } // ---- DÜZLEM ---- if (ImGui::BeginTabItem("◱ Düzlem", nullptr, sekmeBayrak(2))) { g_tur = 2; ImGui::RadioButton("Ofset", &g_duzMod, 0); ImGui::SameLine(); ImGui::RadioButton("3 Nokta", &g_duzMod, 1); ImGui::SameLine(); ImGui::RadioButton("Nokta + Normal", &g_duzMod, 2); ImGui::Separator(); // Oluşturulacak düzlemin konum + normali (moda göre çözülür). bool gecerli = false; Vec3d konum{}, normal{}; // Ofset modu (g_duzMod==0) parametrik: taban gerçek DÜZLEM düğümüyse kaynağı sakla → // referansOfsetDuzlemEkle associative bağ kurar (taban taşınınca ofset takip eder). u32 ofsetKaynak = 0; f64 ofsetMesafe = 0.0; if (g_duzMod == 0) { std::vector tabanlar = tabanDuzlemleriTopla(sahne); if (g_duzTaban >= (int)tabanlar.size()) g_duzTaban = 0; if (ImGui::BeginCombo("Taban Düzlem", tabanlar[g_duzTaban].ad.c_str())) { for (int i = 0; i < (int)tabanlar.size(); ++i) if (ImGui::Selectable(tabanlar[i].ad.c_str(), g_duzTaban == i)) g_duzTaban = i; ImGui::EndCombo(); } ImGui::InputFloat("Mesafe", &g_duzMesafe); const TabanDuzlem& tb = tabanlar[g_duzTaban]; normal = tb.normal; konum = tb.konum + tb.normal * (f64)g_duzMesafe; // normal boyunca ötele ofsetKaynak = tb.kaynak; // 0 = origin (parametrik değil), aksi gerçek düzlem düğümü ofsetMesafe = (f64)g_duzMesafe; gecerli = true; } else if (g_duzMod == 1) { ImGui::InputFloat3("Nokta 1", g_duzP1); ImGui::InputFloat3("Nokta 2", g_duzP2); ImGui::InputFloat3("Nokta 3", g_duzP3); const Vec3d p1 = v3(g_duzP1), p2 = v3(g_duzP2), p3 = v3(g_duzP3); normal = (p2 - p1).capraz(p3 - p1); // düzlem normali = iki kenarın çaprazı konum = p1; gecerli = normal.uzunluk() > 1e-9; if (!gecerli) ImGui::TextColored(SOLUK, "3 nokta aynı doğru üzerinde — normal yok."); } else { ImGui::InputFloat3("Nokta", g_duzNokta); ImGui::InputFloat3("Normal", g_duzNormal); normal = v3(g_duzNormal); konum = v3(g_duzNokta); gecerli = normal.uzunluk() > 1e-9; } if (sketchGir) ImGui::Checkbox("Oluşunca Sketch aç", &g_duzHemenSketch); ImGui::BeginDisabled(!gecerli); if (ImGui::Button("Oluştur", {-1, 0})) { // Ofset modu + gerçek düzlem taban → parametrik (associative); aksi hâlde bağımsız. const Varlik v = (g_duzMod == 0 && ofsetKaynak != 0) ? sahne.referansOfsetDuzlemEkle(ofsetKaynak, ofsetMesafe) : sahne.referansDuzlemEkle(konum, normal); if (v != VARLIK_YOK) { bilgi("Referans düzlem oluşturuldu"); // Kritik: düzlemde SKETCH aç. sketchGir bir SKETCH varlığı bekler → // önce düzlemde sketch üret, sonra ona gir (Sketcher workbench + normal view). if (g_duzHemenSketch && sketchGir) { const Varlik sk = sahne.sketchEkle(v); if (sk != VARLIK_YOK) sketchGir(sk); } } else { bilgi("Düzlem oluşturulamadı: normal geçersiz"); } } ImGui::EndDisabled(); if (gecerli) ImGui::TextColored(YESIL, "● Normal: %.2f %.2f %.2f", normal.x, normal.y, normal.z); ImGui::TextColored(CYAN, "Düzlem seçip 'Sketch Oluştur' ile de sketch açabilirsiniz."); ImGui::EndTabItem(); } ImGui::EndTabBar(); } g_odakIste = -1; // sekme zıplaması tek kare } } // namespace fiko