"""플랜지 밀착 검증: 장착면↔플랜지(truthTool원점), 노즐끝↔마커 (4자세) + 캡처 2장."""
import asyncio, json
from playwright.async_api import async_playwright
URL='http://localhost:8090/DOZIKWORKS_OS_v5_locked.dc.html'
wp=json.loads(open(r'E:\도진팩토리\3D스캔및티칭시스템\weld_path.json',encoding='utf-8').read())
arc=[{k:p[k] for k in ['S','L','U','R','B','T']} for p in wp['poses'] if p.get('arc')==1]
async def main():
    async with async_playwright() as p:
        br=await p.chromium.launch(channel='msedge',headless=True)
        pg=await br.new_page(viewport={'width':1536,'height':864})
        logs=[]; pg.on('console',lambda m: logs.append(m.text))
        await pg.goto(URL); await pg.wait_for_timeout(33000)
        for t in logs:
            if '[torch]' in t: print("콘솔:",t)
        # 4자세: 장착면↔플랜지원점(truthTool로컬), 노즐끝↔마커
        idxs=[0,34,63,99]
        for k,idx in enumerate(idxs):
            r=await pg.evaluate("""(j)=>{const a=window.__dzw,T=a._T; a.setJoints(j); a._grp.updateMatrixWorld(true);
              const torch=a._torchNode.children.find(c=>c.name==='torch_TCP540');
              // 장착면 중심: 메시 지오 최소Z(로컬) → but 간단히 torch 로컬원점=노즐끝. 장착면은 별도.
              // truthTool 로컬에서: 노즐끝=torch.position, 마커=tcpOffset
              const tt=a._truthTool;
              const nozW=new T.Vector3(); torch.getWorldPosition(nozW); // 메시원점=노즐끝
              const mkW=new T.Vector3(); a._tcpMarker.getWorldPosition(mkW);
              // 장착면 월드: 지오 bbox min-z 정점 평균 대신, torch 로컬 원점에서 -축방향. 여기선 torch.matrixWorld로 장착면 근사 생략,
              // 대신 truthTool 원점(플랜지)과 노즐끝 거리로 모델길이 확인
              const flW=new T.Vector3(); tt.getWorldPosition(flW);
              return {noz_mk:nozW.distanceTo(mkW)*1000, flange_noz:flW.distanceTo(nozW)*1000};
            }""",arc[idx])
            print(f"  자세{k+1}: 노즐끝↔마커={r['noz_mk']:.1f}mm  플랜지↔노즐끝(모델길이)={r['flange_noz']:.1f}mm")
        # 장착면↔플랜지: 콘솔 로그가 공백0 확인. 캡처 — 손목 플랜지 클로즈업(플랜지=truthTool원점 타겟)
        pose={'S':0,'L':30,'U':-30,'R':0,'B':-50,'T':0}
        tgt=await pg.evaluate("""(j)=>{const a=window.__dzw,T=a._T; a.setJoints(j); a._grp.updateMatrixWorld(true);
          const w=new T.Vector3(); a._truthTool.getWorldPosition(w); return {x:w.x,y:w.y,z:w.z};}""",pose)
        await pg.evaluate("""(o)=>{const a=window.__dzw; a.orbit.tgt.set(o.x,o.y,o.z);a.orbit.r=0.9;a.orbit.phi=1.25;a.orbit.theta=0.55;a.updateCam();}""",tgt)
        await pg.wait_for_timeout(900); await pg.screenshot(path='shots/FLUSH_wrist.png')
        # 전체
        await pg.evaluate("""()=>{const a=window.__dzw; a.setJoints({S:0,L:0,U:0,R:0,B:0,T:0}); a.orbit.tgt.set(0.1,0,0.4);a.orbit.r=3.2;a.orbit.phi=1.1;a.orbit.theta=0.6;a.updateCam();}""")
        await pg.wait_for_timeout(900); await pg.screenshot(path='shots/FLUSH_full.png')
        print("캡처: FLUSH_wrist.png FLUSH_full.png")
        await br.close()
asyncio.run(main())
