"""
req2 방향 검증: 렌더된 truthTool의 공구 Z축이 torch_dirs.json(RoboDK 0.0001°) 방향벡터와 일치하는가.
위치가 아니라 '방향'을 각도(deg)로 비교.
"""
import asyncio, json, math
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())
td=json.loads(open(r'E:\도진팩토리\3D스캔및티칭시스템\torch_dirs.json',encoding='utf-8').read())['pts']
arc=[p for p in wp['poses'] if p.get('arc')==1]
n=min(len(arc),len(td)); idxs=[0,min(34,n-1),min(63,n-1),min(99,n-1)]
poses4=[{k:arc[i][k] for k in ['S','L','U','R','B','T']} for i in idxs]
dirs4=[[td[i]['dx'],td[i]['dy'],td[i]['dz']] for i in idxs]

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})
        await pg.goto(URL); await pg.wait_for_timeout(32000)
        res=await pg.evaluate("""async (poses)=>{
          const a=window.__dzw,T=a._T; const out=[];
          for(const j of poses){ a.setJoints(j); await new Promise(r=>setTimeout(r,120));
            a._grp.updateMatrixWorld(true);
            const m=a._truthTool.matrixWorld.elements; // column-major, col2=Z축
            let zx=m[8],zy=m[9],zz=m[10]; const L=Math.hypot(zx,zy,zz)||1; zx/=L;zy/=L;zz/=L;
            out.push([zx,zy,zz]);
          } return out;
        }""",poses4)
        print("=== 렌더 공구 Z축 vs torch_dirs(RoboDK) 방향 ===")
        maxang=0
        for lbl,zr,dt in zip(['SEAM-01','SEAM-02','SEAM-03','SEAM-04'],res,dirs4):
            dot=sum(a*b for a,b in zip(zr,dt)); dot=max(-1,min(1,dot))
            ang=math.degrees(math.acos(abs(dot)))  # abs: 축 방향(부호무시) 먼저
            signed=math.degrees(math.acos(dot))
            maxang=max(maxang,ang)
            print(f"  {lbl}: 렌더Z={[round(x,3) for x in zr]} truth={[round(x,3) for x in dt]} 축각도={ang:.3f}° (부호포함 {signed:.1f}°)")
        print(f"  ★ 공구Z축 최대각도차 {maxang:.3f}° →", "통과 ✅" if maxang<0.5 else "실패 ❌ (토치 방향 틀림)")
        await br.close()
asyncio.run(main())
