ModelTranslator: add QR bridge pure logic

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ud18010
2026-07-22 16:40:36 +08:00
co-authored by Claude Opus 4.8
parent 025ce77397
commit 55654e8d33
2 changed files with 151 additions and 0 deletions
+63
View File
@@ -0,0 +1,63 @@
"""QR 桥纯逻辑:引擎发现、面数换算、settings 生成、progress 解析。不 import bpy。
减面可选后端 Quad Remesher 用——headless 直接调 Engine/xremesh.exe,绕开 modal 操作符。"""
import glob
import os
QR_TIMEOUT = 120.0 # 引擎轮询超时(秒)
def find_qr_engine():
"""定位 QuadRemesher 的 xremesh.exe;找不到返回 None。
顺序:QR_ENGINE 环境变量 -> 标准 addon 路径(取最高 Blender 版本目录)。"""
env = os.environ.get("QR_ENGINE")
if env and os.path.isfile(env):
return env
appdata = os.environ.get("APPDATA")
if not appdata:
return None
pattern = os.path.join(
appdata, "Blender Foundation", "Blender", "*",
"scripts", "addons", "QuadRemesher", "Engine", "xremesh.exe")
hits = sorted(glob.glob(pattern))
return hits[-1] if hits else None
def tris_to_target_quads(tris):
"""三角面数换算 QR 目标四边形数:1 quad ≈ 2 tris,至少 1。"""
return max(1, int(tris) // 2)
def build_settings(in_fbx, out_fbx, prog, target_quads,
adaptive=50, exact=False, hard_edges=True):
"""生成 RetopoSettings.txt 文本(xremesh.exe -s 读取)。"""
lines = [
"HostApp=Blender",
'FileIn="%s"' % in_fbx,
'FileOut="%s"' % out_fbx,
'ProgressFile="%s"' % prog,
"TargetQuadCount=%d" % target_quads,
"CurvatureAdaptivness=%d" % adaptive,
"ExactQuadCount=%d" % (1 if exact else 0),
"UseVertexColorMap=False",
"UseMaterialIds=0",
"UseIndexedNormals=0",
"AutoDetectHardEdges=%d" % (1 if hard_edges else 0),
]
return "\n".join(lines) + "\n"
def parse_progress(text):
"""解析 progress.txt -> (state, msg)。
首行 '2'=success<0=error(次行为文本);空/分数/非法=running。"""
lines = text.splitlines()
if not lines:
return ("running", "")
try:
v = float(lines[0])
except ValueError:
return ("running", "")
if v == 2:
return ("success", "")
if v < 0:
return ("error", lines[1] if len(lines) > 1 else "")
return ("running", "")