58 lines
2.2 KiB
Python
58 lines
2.2 KiB
Python
"""Blender 内运行:校验低模 FBX 的 UV 质量门;无 UV 或不达标就地 seam 重展并覆盖导出。
|
|
调用:blender -b --factory-startup --python bl_uvgate.py -- <low.fbx> [mode_label]
|
|
mode_label 仅用于日志/回退警告中标注上游展开方式(默认 rizom)。"""
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
|
def main():
|
|
import bpy
|
|
import json
|
|
from bl_decimate import (join_meshes, uv_gate_ok, _collect_uv_metrics,
|
|
_do_unwrap)
|
|
argv = sys.argv[sys.argv.index("--") + 1:]
|
|
fbx = argv[0]
|
|
mode_label = argv[1] if len(argv) > 1 else "rizom"
|
|
warnings = []
|
|
|
|
bpy.ops.wm.read_factory_settings(use_empty=True)
|
|
bpy.ops.import_scene.fbx(filepath=fbx)
|
|
meshes = [o for o in bpy.data.objects if o.type == 'MESH']
|
|
if not meshes:
|
|
print("MT_SUMMARY " + json.dumps({"error": "FBX 中没有 mesh"},
|
|
ensure_ascii=False))
|
|
return
|
|
obj = join_meshes(meshes)
|
|
|
|
if obj.data.uv_layers:
|
|
m = _collect_uv_metrics(obj)
|
|
if uv_gate_ok(m["flipped"], m["overlap"]):
|
|
m["mode"] = mode_label
|
|
print("MT_SUMMARY " + json.dumps(
|
|
{"uv": m, "reexported": False, "warnings": warnings},
|
|
ensure_ascii=False))
|
|
return
|
|
warnings.append("%s UV 质量不达标(翻转 %.1f%% 重叠 %s),回退 seam"
|
|
% (mode_label, m["flipped"] * 100,
|
|
"%.1f%%" % (m["overlap"] * 100)
|
|
if m["overlap"] is not None else "未知"))
|
|
else:
|
|
warnings.append("%s 输出无 UV,回退 seam" % mode_label)
|
|
|
|
m = _do_unwrap(obj, "seam", warnings) # 内部自带 smart 回退
|
|
if m["mode"] == "seam":
|
|
m["mode"] = "seam_fallback"
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
obj.select_set(True)
|
|
bpy.ops.export_scene.fbx(filepath=os.path.abspath(fbx), use_selection=True,
|
|
path_mode='STRIP', embed_textures=False)
|
|
print("MT_SUMMARY " + json.dumps(
|
|
{"uv": m, "reexported": True, "warnings": warnings},
|
|
ensure_ascii=False))
|
|
|
|
|
|
if __name__ == "__main__" and "--" in sys.argv:
|
|
main()
|