Files

46 lines
2.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""find_blender / run_blender_scriptmodel_decimate 与 model_bake 共享的
headless Blender 运行器(与 model_translator.py 同模式,脚本名与参数泛化)。"""
import collections
import json
import os
import shutil
import subprocess
import sys
DEFAULT_BLENDER = r"D:\tools\blender-5.0.0-windows-x64\blender.exe"
HERE = os.path.dirname(os.path.abspath(__file__))
def find_blender(cli_arg):
for cand in (cli_arg, os.environ.get("BLENDER_EXE"), DEFAULT_BLENDER,
shutil.which("blender")):
if cand and os.path.isfile(cand):
return cand
sys.exit("找不到 blender.exe,请用 --blender 指定或设置环境变量 BLENDER_EXE")
def run_blender_script(blender, script, script_args, blender_args=()):
"""跑 HERE 下的 bl_*.py,返回 MT_SUMMARY JSON;失败或 summary 带 error 则退出。
流式读子进程输出:`MT_PROGRESS ` 行实时转发到本进程 stdout(供上层 UI 显示阶段进度),
`MT_SUMMARY ` 行解析为结果,其余行仅缓存尾部用于出错诊断。stderr 并入 stdout 防管道死锁。"""
cmd = [blender, "-b", *blender_args, "--factory-startup",
"--python", os.path.join(HERE, script), "--"] + list(script_args)
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
text=True, encoding="utf-8", errors="replace", bufsize=1)
summary = None
tail = collections.deque(maxlen=400)
for line in proc.stdout:
line = line.rstrip("\r\n")
if line.startswith("MT_SUMMARY "):
summary = json.loads(line[len("MT_SUMMARY "):])
elif line.startswith("MT_PROGRESS "):
print(line[len("MT_PROGRESS "):], flush=True) # 实时透传给上层
else:
tail.append(line)
proc.wait()
if proc.returncode != 0 or summary is None or "error" in summary:
sys.stderr.write("\n".join(tail)[-2000:] + "\n")
err = summary["error"] if summary and "error" in summary else script
sys.exit("Blender 执行失败:%s" % err)
return summary