// GECICI TESHIS — DERLEMEYE DAHIL DEGIL (kullanici diskindeki Part1-YENI.stp'ye bagli). // Acmak icin: motor/geometri/CMakeLists.txt → fiko_geometri_test kaynaklarina ekle. // Is bitince SILINECEK. Olctugu seyler ve 2026-07-15 sonuclari: // 1) ordinal→mesh (cpuAlt) eslesmesi → KUSURSUZ (28 duz yuz, sapma 0.0000mm) — hipotez OLDU // 2) normal testi (kosul 1) katkisi → SIFIR (occlusion tek basina ayni 16/30/20) // 3) Yuz kipi ALAN yuzdesi vs gercek golge → %81.8 kirmizi vs %52.6 gercek ⭐ KOK NEDEN // 4) Hibrit overlay alani vs beklenen → 0.76 (%24 EKSIK) ⭐ "HIBRIT EKSIK"in olcumu #include "fiko_test.hpp" #include "fiko/geometri/brep.hpp" #include #include #include using namespace fiko; using namespace fiko::geometri; FIKO_TEST(teshis_ordinal_mesh_eslesme) { auto ith = stepYukle("D:/__sistem__/Masaustu/Part1-YENI.stp"); std::printf("govde sayisi=%zu\n", ith.size()); FIKO_KONTROL(!ith.empty()); const BrepGovde& g = ith[0].govde; const MeshVeri m = g.ucgenle({0.5f, 0.5f, 0.5f}); std::printf("mesh: vertex=%zu indeks=%zu yuzSayi=%u\n", m.vertexler.size(), m.indeksler.size(), m.yuzSayi); // ordinal → mesh vertex ortalamasi std::map topla; std::map say; for (const auto& v : m.vertexler) { Vec3d& t = topla[v.altKimlik]; t.x += v.konum[0]; t.y += v.konum[1]; t.z += v.konum[2]; ++say[v.altKimlik]; } f64 maksSapma = 0; u32 maksOrd = 0, kotu = 0, toplam = 0; YuzBilgi yb{}; for (u32 o = 1;; ++o) { YuzBilgi taze{}; if (!g.yuzBilgi(o, taze, /*alanHesapla*/ true)) break; ++toplam; auto it = topla.find(o); if (it == topla.end()) { std::printf("ord=%u MESH YOK (yuzBilgi merkez %.2f %.2f %.2f)\n", o, taze.merkez.x, taze.merkez.y, taze.merkez.z); continue; } const f64 n = (f64)say[o]; const Vec3d mc{it->second.x / n, it->second.y / n, it->second.z / n}; // mesh vertex ortalamasi != agirlik merkezi (esit agirlik degil) → yalniz KABA // kiyas: yuzun bbox'i icinde mi? Basit metrik: mesafe / yuz olcegi. const f64 d = std::sqrt((mc.x - taze.merkez.x) * (mc.x - taze.merkez.x) + (mc.y - taze.merkez.y) * (mc.y - taze.merkez.y) + (mc.z - taze.merkez.z) * (mc.z - taze.merkez.z)); if (d > maksSapma) { maksSapma = d; maksOrd = o; } if (d > 5.0) { ++kotu; if (kotu <= 12) std::printf("ord=%2u SAPMA %.2fmm mesh(%.1f %.1f %.1f) brep(%.1f %.1f %.1f) vtx=%u\n", o, d, mc.x, mc.y, mc.z, taze.merkez.x, taze.merkez.y, taze.merkez.z, say[o]); } } std::printf("TOPLAM yuz=%u · mesh ordinal cesidi=%zu · maks sapma=%.3fmm (ord=%u) · >5mm=%u\n", toplam, topla.size(), maksSapma, maksOrd, kotu); // KESIN TEST: duz yuzde mesh dugumleri o yuzun DUZLEMINDE olmali. // Eslesme kaymissa sapma yuz olceginde (onlarca mm) cikar. std::map> nokta; for (const auto& v : m.vertexler) nokta[v.altKimlik].push_back({v.konum[0], v.konum[1], v.konum[2]}); f64 maksDuzlem = 0; u32 maksDuzlemOrd = 0, duzSayi = 0, duzKotu = 0; for (u32 o = 1;; ++o) { YuzBilgi taze{}; if (!g.yuzBilgi(o, taze, true)) break; if (!taze.duzlemMi) continue; ++duzSayi; f64 en = 0; for (const Vec3d& p : nokta[o]) { const f64 d = std::abs((p.x - taze.merkez.x) * taze.normal.x + (p.y - taze.merkez.y) * taze.normal.y + (p.z - taze.merkez.z) * taze.normal.z); if (d > en) en = d; } if (en > maksDuzlem) { maksDuzlem = en; maksDuzlemOrd = o; } if (en > 0.1) { ++duzKotu; if (duzKotu <= 10) std::printf("DUZLEM KACIK ord=%2u sapma=%.3fmm n(%.2f %.2f %.2f)\n", o, en, taze.normal.x, taze.normal.y, taze.normal.z); } } std::printf("DUZLEM TESTI: duz yuz=%u · maks sapma=%.4fmm (ord=%u) · kacik=%u\n", duzSayi, maksDuzlem, maksDuzlemOrd, duzKotu); // Undercut sonucunu mesh konumuyla capraz-kontrol const auto rap = undercutRapor(g, Donusumd{}, Vec3d{0, 0, 1}); u32 acik = 0, kapali = 0, kismi = 0; for (const auto& u : rap) { if (u.durum == UndercutDurum::Acik) ++acik; else if (u.durum == UndercutDurum::Kapali) ++kapali; else if (u.durum == UndercutDurum::Kismi) ++kismi; } std::printf("undercutRapor(+Z): rapor=%zu acik=%u kapali=%u kismi=%u\n", rap.size(), acik, kapali, kismi); // ⭐ ASIL SORU: BREP "kapali" karari NORMAL testinden mi geliyor? // Shader Golge kipinde (kullanicinin DOGRU dedigi) normal testi YOK — saf occlusion. u32 arka = 0, arkaKapali = 0, onKapali = 0, arkaAcik = 0; for (const auto& u : rap) { YuzBilgi taze{}; if (!g.yuzBilgi(u.ordinal, taze, true)) continue; if (!taze.duzlemMi) continue; const bool arkaYuz = taze.normal.z < -1e-9; // n·(+Z) < 0 if (arkaYuz) ++arka; if (arkaYuz && u.durum == UndercutDurum::Kapali) ++arkaKapali; if (arkaYuz && u.durum == UndercutDurum::Acik) ++arkaAcik; if (!arkaYuz && u.durum == UndercutDurum::Kapali) ++onKapali; } std::printf("DUZ YUZLER: n.z<0 (arka)=%u · bunlardan Kapali=%u Acik=%u · n.z>=0 iken Kapali=%u\n", arka, arkaKapali, arkaAcik, onKapali); // ⭐ KULLANICININ GORDUGU SEY = ALAN YUZDESI. "Yuz kipi tamamen boyuyor" olcumu: // Yuz kipi kismi yuzu KOMPLE kirmizi yapar; gercek golge alani ise oran*alan. f64 topAlan = 0, yuzKipiKirmizi = 0, gercekGolge = 0, kismiAlan = 0; for (const auto& u : rap) { YuzBilgi taze{}; if (!g.yuzBilgi(u.ordinal, taze, true)) continue; topAlan += taze.alan; if (u.durum == UndercutDurum::Kapali) { yuzKipiKirmizi += taze.alan; gercekGolge += taze.alan; } else if (u.durum == UndercutDurum::Kismi) { yuzKipiKirmizi += taze.alan; // KOMPLE kirmizi gercekGolge += taze.alan * (f64)u.ortuluOran; // gercekte bu kadar kismiAlan += taze.alan; std::printf("KISMI ord=%2u oran=%.3f alan=%9.1fmm2 %s%s eksen(%.2f %.2f %.2f) R=%.1f\n", u.ordinal, u.ortuluOran, taze.alan, taze.duzlemMi ? "DUZLEM" : "", taze.silindirMi ? "SILINDIR" : "", taze.eksen.x, taze.eksen.y, taze.eksen.z, taze.yaricap); } } std::printf("\n*** ALAN: toplam=%.0f · Yuz kipi KIRMIZI=%.0f (%%%.1f) · gercek golge=%.0f (%%%.1f)" " · kismi yuz alani=%.0f (%%%.1f) → FAZLA BOYAMA=%.0f mm2\n", topAlan, yuzKipiKirmizi, 100 * yuzKipiKirmizi / topAlan, gercekGolge, 100 * gercekGolge / topAlan, kismiAlan, 100 * kismiAlan / topAlan, yuzKipiKirmizi - gercekGolge); // HIBRIT'in ayagi: kismi yuzler icin EXACT overlay uretilebiliyor mu? std::vector kismiOrd; for (const auto& u : rap) if (u.durum == UndercutDurum::Kismi) kismiOrd.push_back(u.ordinal); std::vector gk, gn; std::vector gi; const bool ok = undercutGolgeMesh(g, Donusumd{}, Vec3d{0, 0, 1}, kismiOrd, gk, gn, gi); std::printf("*** OVERLAY (Hibrit): kismiOrd=%zu → basari=%d vertex=%zu ucgen=%zu\n", kismiOrd.size(), (int)ok, gk.size(), gi.size() / 3); // Overlay alani vs beklenen gercek golge alani (kismi yuzlerin ortulu kismi) f64 ovAlan = 0; for (size_t i = 0; i + 2 < gi.size(); i += 3) { const Vec3f& a = gk[gi[i]]; const Vec3f& b = gk[gi[i + 1]]; const Vec3f& c = gk[gi[i + 2]]; const Vec3f ab{b.x - a.x, b.y - a.y, b.z - a.z}; const Vec3f ac{c.x - a.x, c.y - a.y, c.z - a.z}; const Vec3f cr{ab.y * ac.z - ab.z * ac.y, ab.z * ac.x - ab.x * ac.z, ab.x * ac.y - ab.y * ac.x}; ovAlan += 0.5 * std::sqrt((f64)cr.x * cr.x + (f64)cr.y * cr.y + (f64)cr.z * cr.z); } f64 beklenen = 0; for (const auto& u : rap) { if (u.durum != UndercutDurum::Kismi) continue; YuzBilgi taze{}; if (g.yuzBilgi(u.ordinal, taze, true)) beklenen += taze.alan * (f64)u.ortuluOran; } std::printf("*** OVERLAY ALAN=%.0f mm2 · beklenen (oran*alan)=%.0f mm2 → oran=%.2f\n", ovAlan, beklenen, beklenen > 0 ? ovAlan / beklenen : -1.0); // ⭐ PER-YUZ: hangi kismi yuz overlay URETEMIYOR? (%24 acigin kaynagi) std::printf("\n--- PER-YUZ OVERLAY ---\n"); f64 sifirAlan = 0; u32 sifirSayi = 0; for (u32 o : kismiOrd) { std::vector k1, n1; std::vector i1; const bool b1 = undercutGolgeMesh(g, Donusumd{}, Vec3d{0, 0, 1}, {o}, k1, n1, i1); f64 a1 = 0; for (size_t i = 0; i + 2 < i1.size(); i += 3) { const Vec3f& a = k1[i1[i]]; const Vec3f& b = k1[i1[i + 1]]; const Vec3f& c = k1[i1[i + 2]]; const Vec3f ab{b.x - a.x, b.y - a.y, b.z - a.z}; const Vec3f ac{c.x - a.x, c.y - a.y, c.z - a.z}; const Vec3f cr{ab.y * ac.z - ab.z * ac.y, ab.z * ac.x - ab.x * ac.z, ab.x * ac.y - ab.y * ac.x}; a1 += 0.5 * std::sqrt((f64)cr.x * cr.x + (f64)cr.y * cr.y + (f64)cr.z * cr.z); } YuzBilgi taze{}; g.yuzBilgi(o, taze, true); f64 bek = 0; for (const auto& u : rap) if (u.ordinal == o) bek = taze.alan * (f64)u.ortuluOran; if (a1 < 1e-6) { ++sifirSayi; sifirAlan += bek; } std::printf("ord=%2u basari=%d overlay=%8.1f beklenen=%8.1f oran=%5.2f %s%s\n", o, (int)b1, a1, bek, bek > 0 ? a1 / bek : -1.0, taze.duzlemMi ? "DUZLEM " : "", taze.silindirMi ? "SILINDIR" : (taze.duzlemMi ? "" : "EGRI")); } std::printf("--- OVERLAY URETEMEYEN: %u yuz · kayip beklenen alan=%.0f mm2\n", sifirSayi, sifirAlan); FIKO_KONTROL(true); }