ModelTranslator: Quit/RunRizomUV 走超时通道防挂死 + _call 分支单测(审查修复)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
11d05fbeaa
commit
5de3c17155
@@ -53,7 +53,8 @@ def find_rizomuv(cli_arg=None, use_registry=True, default=DEFAULT_RIZOM):
|
|||||||
|
|
||||||
|
|
||||||
def _import_link(exe):
|
def _import_link(exe):
|
||||||
"""从 RizomUV 安装目录动态引入官方 RizomUVLink 模块(随安装自带,MIT)。"""
|
"""从 RizomUV 安装目录动态引入官方 RizomUVLink 模块(随安装自带,MIT)。
|
||||||
|
同进程只支持单一安装路径(import 缓存,首次 import 后不会再切换目录)。"""
|
||||||
link_dir = os.path.join(os.path.dirname(exe), "RizomUVLink")
|
link_dir = os.path.join(os.path.dirname(exe), "RizomUVLink")
|
||||||
if not os.path.isdir(link_dir):
|
if not os.path.isdir(link_dir):
|
||||||
raise RizomError("RizomUVLink 目录不存在:%s" % link_dir)
|
raise RizomError("RizomUVLink 目录不存在:%s" % link_dir)
|
||||||
@@ -95,8 +96,8 @@ def rizom_unwrap(fbx_path, exe, map_res=MAP_RES, padding_px=PADDING_PX):
|
|||||||
mod = _import_link(exe)
|
mod = _import_link(exe)
|
||||||
link = mod.CRizomUVLink()
|
link = mod.CRizomUVLink()
|
||||||
try:
|
try:
|
||||||
link.RunRizomUV(exePath=exe)
|
_call("RunRizomUV", lambda _p: link.RunRizomUV(exePath=exe), None, timeout=60)
|
||||||
except Exception as e:
|
except RizomError as e:
|
||||||
raise RizomError("RizomUV 启动失败(license/环境):%s" % e)
|
raise RizomError("RizomUV 启动失败(license/环境):%s" % e)
|
||||||
fbx_abs = os.path.abspath(fbx_path)
|
fbx_abs = os.path.abspath(fbx_path)
|
||||||
pad_uv = float(padding_px) / map_res
|
pad_uv = float(padding_px) / map_res
|
||||||
@@ -137,6 +138,6 @@ def rizom_unwrap(fbx_path, exe, map_res=MAP_RES, padding_px=PADDING_PX):
|
|||||||
_call("Save", link.Save, {"File.Path": fbx_abs})
|
_call("Save", link.Save, {"File.Path": fbx_abs})
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
link.Quit({})
|
_call("Quit", link.Quit, {}, timeout=10)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
print("[警告] RizomUV Quit 未确认,可能残留 rizomuv 进程占用 license")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
@@ -35,5 +36,19 @@ class TestFindRizomuv(unittest.TestCase):
|
|||||||
self.assertTrue(os.path.isfile(p), "注册表返回值应是真实 exe:%s" % p)
|
self.assertTrue(os.path.isfile(p), "注册表返回值应是真实 exe:%s" % p)
|
||||||
|
|
||||||
|
|
||||||
|
class TestCall(unittest.TestCase):
|
||||||
|
def test_timeout_raises(self):
|
||||||
|
with self.assertRaises(ru.RizomError) as cm:
|
||||||
|
ru._call("Slow", lambda p: time.sleep(1.0), None, timeout=0.05)
|
||||||
|
self.assertIn("超时", str(cm.exception))
|
||||||
|
|
||||||
|
def test_error_dict_raises(self):
|
||||||
|
with self.assertRaises(ru.RizomError):
|
||||||
|
ru._call("Bad", lambda p: {"Error": {"Msg": "x", "Code": 1}}, {})
|
||||||
|
|
||||||
|
def test_normal_dict_passes_through(self):
|
||||||
|
self.assertEqual(ru._call("Ok", lambda p: {"Data": 1}, {}), {"Data": 1})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user