# -*- coding: utf-8 -*-
"""조립 결과(변환된 실제 정점)를 정면/평면/측면으로 투영해 도면 조립도와 나란히 비교."""
import json, os, math
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib import font_manager, rcParams
for f in ('Malgun Gothic', 'Gulim', 'Batang'):
    if any(f == x.name for x in font_manager.fontManager.ttflist):
        rcParams['font.family'] = f
        break
rcParams['axes.unicode_minus'] = False

SCR = r'C:\Users\user\AppData\Local\Temp\claude\E-----Claude--20260728-claude-code-2-1-219\8defc145-8ae5-48d0-9058-355f3d9ae8ed\scratchpad'
ROOT = r'E:\도진팩토리\3D스캔및티칭시스템'
meta = json.load(open(ROOT + r'\fab_models\assemblies\2110DN-0031_assembly.json', encoding='utf-8'))


def Rx(a):
    c, s = math.cos(a), math.sin(a); return np.array([[1, 0, 0], [0, c, -s], [0, s, c]])


def Ry(a):
    c, s = math.cos(a), math.sin(a); return np.array([[c, 0, s], [0, 1, 0], [-s, 0, c]])


def Rz(a):
    c, s = math.cos(a), math.sin(a); return np.array([[c, -s, 0], [s, c, 0], [0, 0, 1]])


def read_obj(p):
    V, F = [], []
    for ln in open(p, encoding='utf-8', errors='replace'):
        if ln.startswith('v '):
            V.append([float(x) for x in ln.split()[1:4]])
        elif ln.startswith('f '):
            idx = [int(t.split('/')[0]) - 1 for t in ln.split()[1:]]
            F.append(idx)
    return np.array(V), F


COL = ['#1f6feb', '#e07b39', '#2fa66f', '#c04070', '#8f5fd0',
       '#c8a020', '#2f9aa8', '#7a8798', '#d04545', '#4fa050', '#a070d0']

scene = []
for i, p in enumerate(meta['parts']):
    V, F = read_obj(os.path.join(ROOT, p['obj'].replace('/', os.sep)))
    rx, ry, rz = [math.radians(v) for v in p['rot_deg_xyz']]
    R = Rx(rx) @ Ry(ry) @ Rz(rz)          # three.js Euler 'XYZ'
    W = V @ R.T + np.array(p['pos_mm'])
    scene.append((p, W, F, COL[i % len(COL)]))

allv = np.vstack([s[1] for s in scene])
print('조립 전체 bbox mm  min', np.round(allv.min(0), 1), ' max', np.round(allv.max(0), 1))
print('조립 전체 크기      ', np.round(allv.max(0) - allv.min(0), 1))

PROJ = [('정면도 (X-Z, 앞에서)', 0, 2), ('측면도 (Y-Z, 옆에서)', 1, 2), ('평면도 (X-Y, 위에서)', 0, 1)]
fig, axes = plt.subplots(1, 3, figsize=(19, 7))
for ax, (title, a, b) in zip(axes, PROJ):
    for p, W, F, c in scene:
        for f in F:
            pts = W[f][:, [a, b]]
            ax.fill(pts[:, 0], pts[:, 1], color=c,
                    alpha=0.30 if p['ceo_check'] else 0.75, lw=0.4, ec=c)
    ax.set_aspect('equal'); ax.set_title(title, fontsize=12)
    ax.grid(alpha=0.25, lw=0.4)
plt.suptitle('2110DN-0031 CENTER FRAME — 조립 결과 3면 투영 (연한 색 = [CEO확인] 미확정 배치)', fontsize=13)
plt.tight_layout()
plt.savefig(SCR + r'\_asm_proj.png', dpi=140)
print('proj ok')
