我有对 Maya 中的文件运行批处理操作的代码。实际的实现并不重要,只要知道它被提供给文件路径列表,Maya 打开文件,然后依次对每个文件执行操作即可。
如果引用由于任何原因(例如无效路径(无效,我想中止整个场景的加载并跳到批处理列表中的下一个场景。
查看本网站和其他地方的其他问题,我只能看到用户询问如何查询参考文献。我已经有一个合理的函数来这样做,这是在该函数返回一个让我难倒的无效引用路径后该怎么做。
过去,解析无效的引用路径是通过弹出窗口手动完成的,但是在大批量中不断照看 Maya 实例是不可行的。抑制弹出窗口本身也不是,因为我相信它仍然会打开文件,并在场景处于无效状态时在场景上运行批处理操作。
我已经通过 Maya cmds
python 模块来尝试不加载引用,但是当使用 loadReferenceDepth
标志和cmds.file
时,我仍然会收到一个弹出窗口:
cmds.file(r'c:pathtofile.ma', o=1, f=1, lrd='none') #invalid ref popup during file cmd
第二种方法是查看 Maya open api,并在打开之前的事件上注册回调。下面的代码在功能上与批处理的设置方式相同:
import maya.OpenMaya as OpenM
batchFileList = [r"c:pathtofile.ma", r"c:pathtofile2.ma"]
def _test_raise_exception(arg0, arg1, arg2):
#pretending that a file ref failed below. Ref path validation code would go here.
print 'n'*5+'Test Logging'+'n'*5
return False
cId = OpenM.MSceneMessage.addCheckFileCallback(OpenM.MSceneMessage.kBeforeOpenCheck, _test_raise_exception)
for file_ in batchFileList:
try:
rv = cmds.file(file_, o=1)
#do stuff to the maya scene here
except:
#something didn't validate on load, except and skip, logging the occurrence.
print 'load cancelled'
OpenM.MSceneMessage.removeCallback(cId)
但是,即使addCheckFileCallback
指示如果回调函数返回False
操作中止,仍会加载该文件。
同样,将return False
替换为raise RuntimeError
也不会让我捕获异常。相反,cmds.file
完成,只在日志中打印出一条小消息,说"python回调失败"。python open api 文档说绑定更喜欢异常而不是 MStatus 返回代码,所以我希望它能起作用。
我们已经删除了 MStatus 类。 必须使用 Python 异常 而不是 MStatus。
我在这里错过了什么吗?一定有办法做到这一点。建立一个非常粗糙的.ma解析器是另一种选择,但这意味着放弃对.mb文件的支持,我不想这样做。
谢谢你的时间!
您是否尝试过cmds.file
独立lrd = 'none'
和prompt=0
? 这应该可以让您在没有对话框的情况下进入文件,这样您就可以在加载引用之前预先检查引用,如果它们被无聊,请跳过文件。
我在Maya论坛上问过这个问题,并从JoeAlter-Inc句柄的海报中得到了一个非常有用的提示:
您引用的文档适用于 Maya Python API 2,但您使用的类来自 Maya Python API 1。
在 API 1 中,大多数方法采用与 C++ 中完全相同的参数。这意味着 CheckFileCallback 将传递三个参数,其中第一个是对 C++ bool 变量的引用。要中止文件加载,您必须将该变量设置为 false,这需要使用 ctypes 或 MScriptUtil。
在 API 2 中,CheckFileCallback 返回 True 或 False 以指示是否应继续加载文件。因此,在您的示例中更改"导入玛雅"。OpenMaya"到"导入maya.api.OpenMaya"并从_test_raise_exception的参数列表中删除一个参数,你应该很高兴。
我继续测试它,发现如果我提出异常,它就会在内部捕获,并且该过程仍在继续。答案是添加一些outData,在其中设置一个异常,然后检查它是否被击中。
import maya.api.OpenMaya as OpenM
batchFileList = [r"c:pathtofile.ma", r"c:pathtofile2.ma"]
def _test_raise_exception(fileObject, clientData):
#pretending that a file ref failed below. Ref path validation code would go here.
clientData['exception'] = RuntimeError('bad ref {}'.format(fileObject.expandedFullName()))
return False
for file_ in batchFileList:
try:
outData = {}
cId = OpenM.MSceneMessage.addCheckFileCallback(OpenM.MSceneMessage.kBeforeCreateReferenceCheck, _test_raise_exception, clientData=outData)
rv = cmds.file(file_, o=1)
OpenM.MSceneMessage.removeCallback(cId)
if 'exception' in outData: #check if an exception was set, if so, raise it
raise outData['exception']
except:
#handle the exception here
print 'load cancelled'
这样,我可以在批处理过程中加载我的文件,并以pythonic方式处理失败加载的任何异常。