ModelTranslator: bl_decimate 抽取 UV 几何到 sidecar JSON

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ud18010
2026-07-21 11:41:25 +08:00
co-authored by Claude Opus 4.8
parent a19e342bf4
commit 1b8656270d
+31 -1
View File
@@ -326,6 +326,21 @@ def _do_unwrap(obj, mode, warnings):
return m 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(): def main():
import bpy import bpy
import json import json
@@ -364,6 +379,17 @@ def main():
warnings.append("修正 %d 轮后仍超差:%d 面(目标 %d ±3%%" % (MAX_RETRY, cur, target)) warnings.append("修正 %d 轮后仍超差:%d 面(目标 %d ±3%%" % (MAX_RETRY, cur, target))
uv_info = _do_unwrap(obj, unwrap_mode, warnings) 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)) out_dir = os.path.dirname(os.path.abspath(out_fbx))
os.makedirs(out_dir, exist_ok=True) os.makedirs(out_dir, exist_ok=True)
# 仅导出合并后的对象;整场景导出会把 armature/empty 等非 mesh 带进 _low.fbx # 仅导出合并后的对象;整场景导出会把 armature/empty 等非 mesh 带进 _low.fbx
@@ -373,7 +399,11 @@ def main():
print("MT_SUMMARY " + json.dumps( print("MT_SUMMARY " + json.dumps(
{"src": os.path.basename(src), "fbx": os.path.basename(out_fbx), {"src": os.path.basename(src), "fbx": os.path.basename(out_fbx),
"tris_before": orig, "tris_after": cur, "target": target, "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: if __name__ == "__main__" and "--" in sys.argv: