# -*- coding: utf-8 -*-
"""판정 시험: 49·50·77 만 촘촘히 메시하면 '상대 부재의 실제 메시 표면' 에서
간격+1mm 안에 절점이 들어오는가. (CAD 표면이 아니라 서버가 실제로 쓰는 메시가 기준)

왜 CAD 로 재면 안 되는가: 상대 부재(18·17)는 hs=55mm 로 표면을 줄여 메시한다.
그 메시 표면은 CAD 표면에서 떨어져 있을 수 있고, 서버의 판정식은 메시를 쓴다.
"""
import os, pickle, sys
import numpy as np
import fea_server as F

D = pickle.load(open(os.path.join(F.WORK_ROOT, 'conn_diag.pkl'), 'rb'))
byno = {int(p['no']): p for p in D['parts']}
idx_of = {int(p['no']): i for i, p in enumerate(D['parts'])}
MESH = D['mesh']
GN = np.asarray(D['nodes'], float)
WD = os.path.join(F.WORK_ROOT, 'fineprobe2')
os.makedirs(WD, exist_ok=True)

TARGETS = [(49, 18, 2.920), (50, 18, 2.920), (77, 17, 8.000)]
HS = [float(x) for x in (sys.argv[1:] or ['3.92', '5.88'])]

print('상대 부재 메시 보유 여부:', {m: (idx_of[m] in MESH) for _s, m, _g in TARGETS})
for (s, m, gap) in TARGETS:
    need = gap + F.BRIDGE_TOL_MARGIN_MM
    mi = idx_of[m]
    if mi not in MESH:
        print('%d번: 상대 %d번 메시가 덤프에 없음 — 측정 불가' % (s, m)); continue
    MF6 = np.asarray(MESH[mi]['faces6'], np.int64)
    # 기준값: 현재(성긴) 메시에서의 겉면 절점 ↔ 상대 메시
    si = idx_of[s]
    if si in MESH:
        sp0 = GN[np.asarray(MESH[si]['surf_ids'], np.int64)]
        ng0 = F.cad_min_gap(sp0, np.arange(len(sp0)).reshape(-1, 1).repeat(3, 1),
                            GN, MF6[:, :3])
        print('%d번 지금(성긴): 겉면절점 %d개 / 상대 %d번 메시까지 %.3fmm (요구 %.2fmm 안? %s)'
              % (s, len(sp0), m, ng0, need, 'YES' if ng0 <= need else 'NO'))
    P = byno[s]
    V = np.asarray(P['cadV'], float); Fc = np.asarray(P['cadF'], np.int64)
    for h in HS:
        d = os.path.join(WD, 's%d_h%.2f' % (s, h)); os.makedirs(d, exist_ok=True)
        try:
            tm = F.build_tet_mesh_local(V, Fc, d, budget_nodes=1e9,
                                        quality_timeout=180.0, h_target=h)
        except Exception as e:
            print('   목표 %.2fmm: 메시 실패 %r' % (h, e)); continue
        f6, _fo = F.boundary_faces6(tm['elems'])
        sp = tm['nodes'][np.unique(f6[:, :3])]
        ng = F.cad_min_gap(sp, np.arange(len(sp)).reshape(-1, 1).repeat(3, 1), GN, MF6[:, :3])
        print('   목표 %.2fmm → 실제 %.2fmm / 절점 %s / 겉면절점 %d / 상대 메시까지 %.3fmm '
              '→ 요구 %.2fmm 안? %s'
              % (h, tm['elem_size_mm'], '{:,}'.format(len(tm['nodes'])), len(sp), ng,
                 need, 'YES' if ng <= need else 'NO'))
