#pragma once // DM AKILLI YENİDEN DÜZENLEME: mevcut bir fillet/chamfer feature'ının bevel YÜZÜNE tıkla-sürükle → // o feature'ın yarıçap/mesafe parametresini güncelle (YENİ feature stacklemez — parametrik). partD. // yuzFeatureBul yüz ordinalinden üreten feature'ı bulur (feature en üstteyken geçerli). Bırakışta // featureGuncelle → zincir yeniden hesaplanır. Kullanıcı: "pahın yüzüne tıkla-sürükle → güncellesin". #include #include #include #include #include "fiko/cekirdek/cekirdek.hpp" #include "fiko/parca/part_design_sistemi.hpp" #include "fiko/render/orbit_kamera.hpp" #include "fiko/sahne/sahne.hpp" #include "fiko/ui/bilesen_ek.hpp" #include "dogrudan_ayar.hpp" #include "gizmo_gorsel.hpp" #include "imgui.h" namespace fiko { struct FeatureReDuzenleDurum { bool aktif = false; bool surukluyor = false; bool tutamacYakin = false; // imleç tutamaçta — TUŞTAN BAĞIMSIZ (dokunmatik; bkz. kenar_fillet.hpp) u32 feature = 0; bool fillet = true; // fillet(yaricap) / chamfer(mesafe) bool itcek = false; // true=yuz_itcek (mesafe, İŞARETLİ) — fillet/chamfer'dan ayrı renk/harf Vec3f merkezD{}; ImVec2 merkezEkran{}; f32 basMesafe = 0; // tıklama anı imleç-merkez uzaklığı (delta taban) f32 basDeger = 0; // sürükleme başı parametre değeri f32 deger = 0; // canlı değer char tipBuf[24] = ""; }; inline void featureReDuzenleCizVeIsle(FeatureReDuzenleDurum& fd, Sahne& sahne, parca::PartDesignSistemi& partD, OrbitKamera& kamera, ImDrawList* dl, ImGuiIO& io, bool vpHover, f32 mx, f32 my, f32 vw, f32 vh, f32 enBoy, bool& ustunde) { ustunde = false; if (!fd.aktif) return; const Mat4f vp = kamera.izdusum(enBoy) * kamera.gorunum(); const auto proj = [&](const Vec3f& p, ImVec2& s) -> bool { const Vec4f h = vp * Vec4f{p, 1.0f}; if (h.w <= 1e-4f) return false; s = ImVec2(mx + (h.x / h.w * 0.5f + 0.5f) * vw, my + (h.y / h.w * 0.5f + 0.5f) * vh); return true; }; if (!fd.surukluyor) { if (sahne.kip() != SecimKip::Yuz) return; u32 g = 0, a = 0; for (const SecimOge& o : sahne.secililer()) if (o.alt > 0) { g = o.govde; a = o.alt; break; } if (!g || !a) return; const u32 fk = partD.yuzFeatureBul(g, a); // bu yüzü üreten fillet/chamfer feature if (!fk) return; const std::string tip = partD.featureTip(fk); const bool fillet = (tip == "fillet"); const bool itcek = (tip == "yuz_itcek"); if (!fillet && tip != "chamfer" && !itcek) return; Dugum* d = sahne.bul(g); geometri::YuzBilgi yb; if (!d || !d->brep || !d->brep->yuzBilgi(a, yb)) return; // Push/pull'ın it/çek oku düz/silindir/küre/koni yüzlerde feature'ı ZATEN düzenliyor → // çift-gizmo/çift-uygulama olmasın diye burada yalnız push/pull'ın DEĞMEDİĞİ yüzler (torus // fillet vb.) merkez-tutamaç ile düzenlenir. if (yb.duzlemMi || yb.silindirMi || yb.kureMi || yb.koniMi) return; const Vec3d w = d->donusum.noktaUygula(yb.merkez); const Vec3f merkez{(f32)w.x, (f32)w.y, (f32)w.z}; ImVec2 sc; if (!proj(merkez, sc)) return; const f32 mdx = sc.x - io.MousePos.x, mdy = sc.y - io.MousePos.y; const f32 hr = 13.0f * dokunmaHedefCarpani(); // parmakta büyür, farede 13px const bool yakin = vpHover && (mdx * mdx + mdy * mdy) <= hr * hr; ustunde = yakin && ImGui::IsMouseDown(ImGuiMouseButton_Left); fd.tutamacYakin = yakin; // dokunmatik: tuştan bağımsız yakınlık const char* key = fillet ? "yaricap" : "mesafe"; // chamfer + yuz_itcek → mesafe const f32 cur = (f32)partD.featureDeger(fk, key); const ImU32 renk = itcek ? IM_COL32(120, 220, 255, 255) : (fillet ? IM_COL32(120, 200, 255, 255) : IM_COL32(255, 170, 90, 255)); const f32 rad = (yakin ? 11.0f : 9.0f) * dogrudanAyar().tutamacBoy; if (yakin && dogrudanAyar().glowAcik) gizmo::glowDaire(dl, sc, rad, renk); dl->AddCircleFilled(sc, rad, yakin ? renk : IM_COL32(40, 44, 52, 235)); dl->AddCircle(sc, rad, renk, 0, yakin ? 2.5f : 1.8f); const char* harf = itcek ? "↕" : (fillet ? "R" : "C"); const ImVec2 ts = ImGui::CalcTextSize(harf); dl->AddText({sc.x - ts.x * 0.5f, sc.y - ts.y * 0.5f}, yakin ? IM_COL32(20, 24, 30, 255) : renk, harf); if (yakin) { char b[48]; std::snprintf(b, sizeof(b), "%s %.2f mm ✎", itcek ? "↕" : (fillet ? "◜ R" : "◺ pah"), cur); gizmo::degerEtiketi(dl, {sc.x, sc.y - 24.0f}, b, renk); } if (yakin && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { fd.surukluyor = true; fd.feature = fk; fd.fillet = fillet; fd.itcek = itcek; fd.merkezD = merkez; fd.merkezEkran = sc; const f32 dx = io.MousePos.x - sc.x, dy = io.MousePos.y - sc.y; fd.basMesafe = std::sqrt(dx * dx + dy * dy); fd.basDeger = cur; fd.deger = cur; fd.tipBuf[0] = 0; } return; } // ---- Sürükleme: değeri mevcut R/C'den itibaren ayarla (fillet gizmo ile aynı ölçek) ---- ustunde = true; const f32 dx = io.MousePos.x - fd.merkezEkran.x, dy = io.MousePos.y - fd.merkezEkran.y; const f32 ekranMesafe = std::sqrt(dx * dx + dy * dy); const Vec3f kamSag = kamera.yukari().capraz(kamera.kameraYonu()).birim(); ImVec2 sM, sS; f32 pikselPerMm = 1.0f; if (proj(fd.merkezD, sM) && proj(fd.merkezD + kamSag, sS)) { const f32 px = sS.x - sM.x, py = sS.y - sM.y; pikselPerMm = std::max(std::sqrt(px * px + py * py), 1e-4f); } const f32 ham = fd.basDeger + (ekranMesafe - fd.basMesafe) / pikselPerMm * dogrudanAyar().filletHassas; fd.deger = fd.itcek ? ham : std::max(ham, 0.0f); // it/çek işaretli kalır (fillet/pah ≥0) for (int i = 0; i < io.InputQueueCharacters.Size; ++i) { const ImWchar c = io.InputQueueCharacters[i]; const size_t l = std::strlen(fd.tipBuf); if (((c >= '0' && c <= '9') || c == '.') && l < sizeof(fd.tipBuf) - 1) { fd.tipBuf[l] = (char)c; fd.tipBuf[l + 1] = 0; } } if (ImGui::IsKeyPressed(ImGuiKey_Backspace)) { const size_t l = std::strlen(fd.tipBuf); if (l) fd.tipBuf[l - 1] = 0; } if (fd.tipBuf[0]) fd.deger = (f32)std::atof(fd.tipBuf); const ImU32 renk = fd.itcek ? IM_COL32(120, 220, 255, 255) : (fd.fillet ? IM_COL32(120, 200, 255, 255) : IM_COL32(255, 170, 90, 255)); dl->AddLine(fd.merkezEkran, io.MousePos, renk, 2.0f); dl->AddCircleFilled(fd.merkezEkran, 4.0f, renk); const char* etk = fd.itcek ? "↕" : (fd.fillet ? "◜ R" : "◺ pah"); char b[48]; if (fd.tipBuf[0]) std::snprintf(b, sizeof(b), "%s %s mm ▏", etk, fd.tipBuf); else std::snprintf(b, sizeof(b), "%s %.2f mm", etk, fd.deger); gizmo::degerEtiketi(dl, io.MousePos, b, renk); if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { const u32 fk = fd.feature; const bool fil = fd.fillet; const bool ic = fd.itcek; const f32 v = fd.deger; fd.surukluyor = false; fd.tipBuf[0] = 0; if (fk && (ic ? std::abs(v) > 1e-3f : v > 1e-3f)) { partD.featureGuncelle(fk, fil ? "yaricap" : "mesafe", (f64)v); // parametrik güncelle + recompute ui::toastGoster(ic ? "Yüz İt/Çek güncellendi" : (fil ? "Fillet güncellendi" : "Chamfer güncellendi"), ui::ToastTip::Basari); } } } } // namespace fiko