# -*- coding: utf-8 -*-
"""49·50·77(+상대 18·17) 만 요소크기를 내려 메시하면 절점이 몇 개가 되는지,
그리고 겉면 절점↔상대 CAD 표면 최소거리가 CAD 간격까지 좁혀지는지 실측한다.
전체 해석을 돌리기 전에 '100만 절점을 넘지 않는가' 를 먼저 확인하는 통제시험이다."""
import os, pickle, sys, time
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']}
WD = os.path.join(F.WORK_ROOT, 'fineprobe')
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 ['2.0'])]

for h in HS:
    print('=== 목표 요소크기 %.2fmm ===' % h, flush=True)
    for (s, m, gap) in TARGETS:
        P = byno[s]
        V = np.asarray(P['cadV'], float); Fc = np.asarray(P['cadF'], np.int64)
        d = os.path.join(WD, 's%d_h%.1f' % (s, h)); os.makedirs(d, exist_ok=True)
        t0 = time.time()
        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('  %d번: 메시 실패 %r' % (s, e)); continue
        nd = tm['nodes']
        # 겉면 절점 추출
        f6, _fo = F.boundary_faces6(tm['elems'])
        sid = np.unique(f6[:, :3])
        sp = nd[sid]
        M = byno[m]
        MV = np.asarray(M['cadV'], float); MF = np.asarray(M['cadF'], np.int64)
        ng = F.cad_min_gap(sp, np.arange(len(sp)).reshape(-1, 1).repeat(3, 1), MV, MF)
        base = byno[s]
        print('  %d번(상대 %d번) CAD간격 %.3f / 실제h %.2fmm / 절점 %s / 겉면절점 %d '
              '/ 겉면절점↔상대CAD %.3fmm → 간격+1 안? %s (%.0f초)'
              % (s, m, gap, tm['elem_size_mm'], '{:,}'.format(len(nd)), len(sp),
                 ng, 'YES' if ng <= gap + 1.0 else 'NO', time.time() - t0), flush=True)
