我有代码对Maya中的文件运行批处理操作。实际的实现并不重要,只要知道它被提供了一个文件路径列表,maya打开文件,然后依次对每个文件执行操作。
如果引用因任何原因无效(如无效路径),我想中止加载整个场景并跳到批处理列表中的下一个。
查看本网站和其他地方的其他问题,我只能看到用户询问如何查询引用。我已经有了这样做的合理功能,它是在该函数返回一个无效的引用路径之后要做的事情。
历史上已经通过弹出窗口手动完成了解析无效引用路径,但是在大批量中不断地对maya实例进行保护是不可行的。也没有抑制弹出窗口本身,因为我相信它仍会打开文件,并在场景处于无效状态时运行批处理操作。
我已经通过the maya cmds
python module尝试不加载引用,但是当使用loadReferenceDepth
标记和cmds.file
时,我仍然会收到弹出窗口:
cmds.file(r'c:\path\to\file.ma', o=1, f=1, lrd='none') #invalid ref popup during file cmd
第二种方法是查看maya open api并在打开前事件中注册回调。以下代码在功能上与批处理的设置方式相同:
import maya.OpenMaya as OpenM
batchFileList = [r"c:\path\to\file.ma", r"c:\path\to\file2.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
indicates that if the callback function returns False
the operation is aborted,也会加载文件。
同样,将return False
替换为raise RuntimeError
不会让我抓住异常。相反,cmds.file
完成,只在日志中打印出一条消息“python callback failed”。 The python open api docs say that the bindings prefer exceptions over MStatus return codes though, so I would've expected that to work.
我们删除了MStatus类。必须使用Python异常 而不是MStatus。
我在这里遗漏了什么吗?必须有办法做到这一点。构建一个非常粗糙的.ma解析器是另一种选择,但这意味着放弃对.mb文件的支持,我不想这样做。
谢谢你的时间!
答案 0 :(得分:1)
我在Maya论坛和got a very helpful hint from a poster by the handle of JoeAlter-Inc上问了这个问题:
您引用的文档是针对Maya Python API 2的,但是您使用的类来自Maya Python API 1。
在API 1中,大多数方法采用与C ++中完全相同的参数。这意味着CheckFileCallback将传递三个参数,第一个是对C ++ bool变量的引用。要中止文件加载,必须将该变量设置为false,这需要使用ctypes或MScriptUtil。
在API 2中,CheckFileCallback返回True或False,以指示是否应继续进行文件加载。因此,在您的示例中,将“ import maya.OpenMaya”更改为“ import maya.api.OpenMaya”,并从_test_raise_exception的参数列表中删除一个参数,您应该会做得很好。
我继续对其进行测试,发现如果我提出异常,它将在内部被捕获,并且该过程继续进行。答案是添加一些outData,在其中设置一个异常,然后检查它是否之后被击中。
import maya.api.OpenMaya as OpenM
batchFileList = [r"c:\path\to\file.ma", r"c:\path\to\file2.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方式处理加载失败时的所有异常。
答案 1 :(得分:0)
您是否已尝试cmds.file
并lrd = 'none'
和prompt=0
独立?这应该会让你进入没有对话框的文件,所以你可以在加载之前预先检查引用,如果它们被borked则跳过文件。