2

我有在 Maya 中对文件运行批处理操作的代码。实际的实现并不重要,只要知道它得到一个文件路径列表,maya 打开文件,然后依次对每个文件执行操作。

如果由于某种原因引用无效(例如路径无效),我想中止加载整个场景并跳到批处理列表中的下一个。

查看此站点和其他地方的其他问题,我只能看到用户询问如何查询参考。我已经有一个合理的函数来执行此操作,这是在该函数返回一个让我难过的无效引用路径之后要做的事情。

过去一直通过弹出窗口手动解决无效的参考路径,但是大批量不断地照看 Maya 实例是不可行的。也不会抑制弹出窗口本身,因为我相信它仍然会打开文件,并在它处于无效状态时在现场运行批处理操作。

我已经通过maya cmdspython模块尝试不加载引用,但是当使用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并在 before open 事件上注册一个回调。下面的代码在功能上与批处理的设置方式相同:

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表明如果回调函数返回False操作是 aborted,文件还是会被加载。

同样,替换return Falsefor araise RuntimeError不会让我捕捉到异常。相反,cmds.file完成并且只在日志中打印出一条小消息,说“python回调失败”。python open api 文档说绑定更喜欢异常而不是 MStatus 返回代码,所以我希望它可以工作。

我们删除了 MStatus 类。必须使用 Python 异常而不是 MStatus。

我在这里错过了什么吗?必须有办法做到这一点。构建一个非常粗糙的 .ma 解析器是另一种选择,但这意味着放弃对 .mb 文件的支持,我不想这样做。

谢谢你的时间!

4

2 回答 2

1

我在 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 以指示是否应该继续加载文件。因此,在您的示例中,将 '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'

这样,我可以在批处理过程中加载我的文件,并以 python 方式处理来自失败加载的任何异常。

于 2018-07-02T08:31:36.403 回答
0

您是否尝试过独立cmds.file使用?这应该让您在没有对话框的情况下进入文件,这样您就可以在加载它们之前预先检查引用,如果它们被破坏则跳过文件。lrd = 'none'prompt=0

于 2018-05-04T20:15:08.730 回答