"""[Step2] CAD 검증 — 자 1벌(measureTCP) + 장착면 밀착(★실제 드로잉 정점 평면, 자기충족 금지) + 캡처."""
import asyncio, json
import numpy as np
from playwright.async_api import async_playwright
URL='http://localhost:8090/DOZIKWORKS_OS_v5_locked.dc.html'
OUT=r'E:\도진팩토리\3D스캔및티칭시스템\shots\ceo_feedback'
CEO_HOME={"S":-0.7,"L":-59.4,"U":-44.4,"R":-1.0,"B":-92.9,"T":-1.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':1400,'height':950})
        errs=[]; pg.on('pageerror',lambda e: errs.append(str(e)))
        await pg.goto(URL); await pg.wait_for_function("window.__dzw && window.__dzw._torchMesh && window.__dzw._torchMountC",timeout=15000)
        data=await pg.evaluate("""(HOME)=>{ const d=window.__dzw,T=d._T;
          if(d.setJoints) d.setJoints(HOME);
          const me=d._torchMesh, tt=d._truthTool; me.updateMatrixWorld(true); tt.updateMatrixWorld(true);
          const m=d.measureTCP();
          // ★ 실제 드로잉 정점: 모델 C_m 근처(<45mm) 정점을 truthTool-로컬로 (자기충족 아님 — 진짜 그려지는 위치)
          const Cm=d._torchMountC; const g=me.geometry, pos=g.attributes.position; const out=[]; const v=new T.Vector3();
          for(let i=0;i<pos.count;i++){ v.fromBufferAttribute(pos,i); if(v.distanceTo(Cm)<45){ const w=v.clone().applyMatrix4(me.matrixWorld); const l=tt.worldToLocal(w); out.push([+l.x.toFixed(2),+l.y.toFixed(2),+l.z.toFixed(2)]); } }
          const box=new T.Box3().setFromObject(me); const c=new T.Vector3(); box.getCenter(c);
          if(d.orbit){ d.orbit.tgt.copy(c); d.orbit.r=0.5; d.orbit.theta=-0.7; d.orbit.phi=1.45; d.updateCam&&d.updateCam(); }
          return { name:me.name, measure:m, mountVerts:out }; }""", CEO_HOME)
        await pg.wait_for_timeout(500)
        await pg.screenshot(path=OUT+r'\fix_cad_torch_1.png')
        F=np.array(data['mountVerts']); c=F.mean(0); M=F-c
        u,s,vt=np.linalg.svd(M,full_matrices=False); n=vt[2]
        if n[2]<0: n=-n
        tilt=np.degrees(np.arccos(min(1,abs(n@np.array([0,0,1.0])))))
        print("=== CAD 검증 (자 1벌 + 실제정점 밀착) ===")
        print(" 메시:", data['name'], "| 장착면 정점수:", len(F))
        print(" 노즐끝↔NOZZLE_TCP:", data['measure']['nozzle_to_NOZZLE_TCP'], "mm")
        print(" 와이어끝↔WIRE_TCP:", data['measure']['wire_to_WIRE_TCP'], "mm")
        print(" 장착면 중심(truthTool-로컬):", c.round(2).tolist())
        print(" 장착면 간극(|중심|):", round(float(np.linalg.norm(c)),2), "mm  / z(플랜지면0까지):", round(float(abs(c[2])),2), "mm")
        print(" 장착면 기울기(vs 손목+Z):", round(float(tilt),2), "도")
        print(" 캡처: fix_cad_torch_1.png  | errs:", errs if errs else "없음")
asyncio.run(main())
