diff --git a/Tools/ModelTranslator/bl_decimate.py b/Tools/ModelTranslator/bl_decimate.py index 0a9864ed..25b2f3c0 100644 --- a/Tools/ModelTranslator/bl_decimate.py +++ b/Tools/ModelTranslator/bl_decimate.py @@ -326,6 +326,21 @@ def _do_unwrap(obj, mode, warnings): return m +def _collect_uv_polygons(obj): + """提取每个面的 UV 多边形(归一化坐标):[[[u,v], ...], ...],供外部 PIL 绘图。 + 无 UV 层返回空列表。""" + import bmesh + bm = bmesh.new() + bm.from_mesh(obj.data) + uv = bm.loops.layers.uv.active + polys = [] + if uv is not None: + for f in bm.faces: + polys.append([[l[uv].uv.x, l[uv].uv.y] for l in f.loops]) + bm.free() + return polys + + def main(): import bpy import json @@ -364,6 +379,17 @@ def main(): warnings.append("修正 %d 轮后仍超差:%d 面(目标 %d ±3%%)" % (MAX_RETRY, cur, target)) uv_info = _do_unwrap(obj, unwrap_mode, warnings) + uv_png = os.path.splitext(os.path.abspath(out_fbx))[0] + "_uv.png" + uv_polys_json = os.path.splitext(os.path.abspath(out_fbx))[0] + "_uv.polys.json" + uv_preview = None + try: + polys = _collect_uv_polygons(obj) + os.makedirs(os.path.dirname(uv_polys_json), exist_ok=True) + with open(uv_polys_json, "w", encoding="utf-8") as fp: + json.dump(polys, fp) + uv_preview = uv_png # 目标 PNG;实际绘制由 model_decimate(系统 Python + PIL)完成 + except Exception as e: + warnings.append("UV 几何导出失败(%s),跳过观察图" % e) out_dir = os.path.dirname(os.path.abspath(out_fbx)) os.makedirs(out_dir, exist_ok=True) # 仅导出合并后的对象;整场景导出会把 armature/empty 等非 mesh 带进 _low.fbx @@ -373,7 +399,11 @@ def main(): print("MT_SUMMARY " + json.dumps( {"src": os.path.basename(src), "fbx": os.path.basename(out_fbx), "tris_before": orig, "tris_after": cur, "target": target, - "uv": uv_info, "warnings": warnings}, ensure_ascii=False)) + "uv": uv_info, + "uv_preview": uv_preview, + "uv_polys": uv_polys_json if uv_preview else None, + "warnings": warnings}, + ensure_ascii=False)) if __name__ == "__main__" and "--" in sys.argv: