I have code that runs a batch operation on files in Maya. The actual implementation isn't important, just know that it gets fed a list of filepaths, maya opens the files, then an operation is performed on each file in turn.
In cases where a reference isn't valid for whatever reason (like an invalid path) I want to abort loading of that whole scene and skip to the next in the batch list.
Looking at other questions on this site and elsewhere I've only been able to see users asking how to query references. I already have a reasonable function for doing so, it's what to do after that function returns an invalid reference path that stumps me.
Resolving invalid reference paths has historically been done manually via the popup, however in large batches constantly babysitting the maya instance isn't feasible. Nor is suppressing the popup window itself, as I believe that will still open the file, and run the batch operation on the scene while it's in an invalid state.
I have been through the maya cmds
python module to try and not load references, however when using the loadReferenceDepth
flag along with cmds.file
I'm still getting a popup:
cmds.file(r'c:\path\to\file.ma', o=1, f=1, lrd='none') #invalid ref popup during file cmd
The second approach was to look into the maya open api and register a callback on the before open event. The code below is functionally the same as how the batch is set up:
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)
However, even though the addCheckFileCallback
indicates that if the callback function returns False
the operation is aborted, the file is loaded anyway.
Likewise, replacing the return False
for a raise RuntimeError
doesn't let me catch the exception. Instead the cmds.file
completes and only prints out a small message in the log saying "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.
We have removed the MStatus class. Python exceptions must be used instead of MStatus.
Am I missing something here? There must be a way to do this. Building up a very crude .ma parser is another option but that would mean dropping support for .mb files, which I don't want to do.
Thanks for your time!