"""현재 손목-플랜지-토치 상태 캡처 + 플랜지 화면좌표 클릭 시 무엇이 raycast로 잡히는지."""
import asyncio
from playwright.async_api import async_playwright
URL='http://localhost:8090/DOZIKWORKS_OS_v5_locked.dc.html'
OUT=r'E:\도진팩토리\3D스캔및티칭시스템\shots\ceo_feedback'

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_function("window.__dzw && window.__dzw._torchPivot", timeout=15000)
        # 손목-플랜지 클로즈업 뷰로 카메라 이동 (토치 피벗 중심을 바라봄)
        await pg.evaluate("""()=>{ const d=window.__dzw, T=d._T;
          const piv=d._torchPivot; const wc=new T.Vector3(); piv.getWorldPosition(wc);
          if(d.orbit){ d.orbit.tgt.copy(wc); d.orbit.r=1.1; d.orbit.theta=-0.7; d.orbit.phi=1.35; d.updateCam&&d.updateCam(); }
        }""")
        await pg.wait_for_timeout(400)
        await pg.screenshot(path=OUT+r'\FLANGE_probe_full.png')
        # 씬 전체를 raycast: 카메라에서 화면 중앙(토치 피벗=플랜지 근처)로 쏴서 맞는 것들 나열
        res=await pg.evaluate("""()=>{ const d=window.__dzw, T=d._T; const cam=d.three.cam;
          const piv=d._torchPivot; const wc=new T.Vector3(); piv.getWorldPosition(wc);
          // 플랜지 지점 월드좌표를 화면 NDC로 투영
          const ndc=wc.clone().project(cam);
          const ray=new T.Raycaster(); ray.setFromCamera({x:ndc.x,y:ndc.y}, cam);
          const all=[]; d.three.scene.traverse(o=>{ if(o.isMesh) all.push(o); });
          d._selectModeActive=true; // 토치 raycast 켜기
          const hits=ray.intersectObjects(all,true);
          d._selectModeActive=false;
          return {ndc:[+ndc.x.toFixed(2),+ndc.y.toFixed(2)],
            hits:hits.slice(0,6).map(h=>({name:h.object.name||'(no name)', dist:+h.distance.toFixed(3)}))};
        }""")
        import json; print(json.dumps(res,ensure_ascii=False,indent=1))
        await br.close()

asyncio.run(main())
