ModelTranslator: harden QR fallback (cleanup-in-try, wait after kill, keep engine error)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
be09397609
commit
687bc99aea
@@ -126,7 +126,7 @@ def _remesh_quad(obj, target_tris, warnings):
|
||||
import time
|
||||
engine = qr_bridge.find_qr_engine()
|
||||
if not engine:
|
||||
warnings.append("未找到 QuadRemesher 引擎(xremesh.exe),回退 collapse")
|
||||
warnings.append("未找到 QuadRemesher 引擎(xremesh.exe),回退 collapse")
|
||||
return False
|
||||
work = os.path.join(tempfile.gettempdir(), "mt_qr")
|
||||
os.makedirs(work, exist_ok=True)
|
||||
@@ -134,10 +134,10 @@ def _remesh_quad(obj, target_tris, warnings):
|
||||
out_fbx = os.path.join(work, "retopo.fbx").replace("\\", "/")
|
||||
prog = os.path.join(work, "progress.txt").replace("\\", "/")
|
||||
settings = os.path.join(work, "RetopoSettings.txt")
|
||||
for f in (out_fbx, prog):
|
||||
if os.path.isfile(f):
|
||||
os.remove(f)
|
||||
try:
|
||||
for f in (out_fbx, prog):
|
||||
if os.path.isfile(f):
|
||||
os.remove(f)
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
obj.select_set(True)
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
@@ -147,7 +147,7 @@ def _remesh_quad(obj, target_tris, warnings):
|
||||
fp.write(qr_bridge.build_settings(in_fbx, out_fbx, prog, target_quads))
|
||||
proc = subprocess.Popen([engine, "-s", settings])
|
||||
except Exception as e:
|
||||
warnings.append("QR 启动失败(%s),回退 collapse" % e)
|
||||
warnings.append("QR 启动失败(%s),回退 collapse" % e)
|
||||
return False
|
||||
|
||||
t0 = time.time()
|
||||
@@ -158,26 +158,27 @@ def _remesh_quad(obj, target_tris, warnings):
|
||||
state, msg = qr_bridge.parse_progress(fp.read())
|
||||
except IOError:
|
||||
state, msg = "running", ""
|
||||
if state == "success":
|
||||
if state in ("success", "error"):
|
||||
break
|
||||
if state == "error":
|
||||
warnings.append("QR 重拓扑失败(%s),回退 collapse" % msg)
|
||||
return False
|
||||
if proc.poll() is not None:
|
||||
# 进程已退出:给 progress/输出一点落地时间后再判一次
|
||||
time.sleep(QR_POLL_INTERVAL)
|
||||
try:
|
||||
with open(prog) as fp:
|
||||
state, _ = qr_bridge.parse_progress(fp.read())
|
||||
state, msg = qr_bridge.parse_progress(fp.read())
|
||||
except IOError:
|
||||
state = "running"
|
||||
state, msg = "running", ""
|
||||
break
|
||||
if time.time() - t0 > qr_bridge.QR_TIMEOUT:
|
||||
proc.kill()
|
||||
warnings.append("QR 超时(%ds),回退 collapse" % int(qr_bridge.QR_TIMEOUT))
|
||||
proc.wait()
|
||||
warnings.append("QR 超时(%ds),回退 collapse" % int(qr_bridge.QR_TIMEOUT))
|
||||
return False
|
||||
time.sleep(QR_POLL_INTERVAL)
|
||||
|
||||
if state == "error":
|
||||
warnings.append("QR 重拓扑失败(%s),回退 collapse" % msg)
|
||||
return False
|
||||
if state != "success" or not (
|
||||
os.path.isfile(out_fbx) and os.path.getsize(out_fbx) > 0):
|
||||
warnings.append("QR 无有效输出,回退 collapse")
|
||||
@@ -192,13 +193,13 @@ def _remesh_quad(obj, target_tris, warnings):
|
||||
warnings.append("QR 导回无 mesh,回退 collapse")
|
||||
return False
|
||||
retopo = new[0]
|
||||
bpy.data.objects.remove(obj, do_unlink=True)
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
retopo.select_set(True)
|
||||
bpy.context.view_layer.objects.active = retopo
|
||||
bpy.data.objects.remove(obj, do_unlink=True)
|
||||
return True
|
||||
except Exception as e:
|
||||
warnings.append("QR 导回失败(%s),回退 collapse" % e)
|
||||
warnings.append("QR 导回失败(%s),回退 collapse" % e)
|
||||
return False
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user