Source code for cgl.plugins.maya.standalone

import sys
import subprocess
import os
import importlib
import pickle
from traceback import format_exception
import tempfile

try:
    import unreal
except:
    unreal = None

MAYAPY = "C:\\Program Files\\Autodesk\\Maya2024\\bin\\mayapy.exe"

[docs] def test_func(): return "test result"
[docs] class MayaStandAloneException(Exception): pass
[docs] def rebuild_exc(exc, tb): exc.__cause__ = MayaStandAloneException(tb) return exc
[docs] class MayaStandAloneExceptionPickle(object): def __init__(self, exc, tb): tb = ''.join(format_exception(type(exc), exc, tb)) self.exc = exc # Traceback object needs to be garbage-collected as its frames # contain references to all the objects in the exception scope self.exc.__traceback__ = None self.tb = '\n"""\n%s"""' % tb def __reduce__(self): return rebuild_exc, (self.exc, self.tb)
[docs] class MayaStandAloneResult: def __init__(self): self.exc = None self.result = None
[docs] def main_maya(result_file): ret = MayaStandAloneResult() try: in_data = sys.stdin.buffer.read() entrypoint, args, kwargs = pickle.loads(in_data) print(entrypoint, args, kwargs) module_name, func_name = entrypoint.split(":") from maya import standalone standalone.initialize(name='python') from maya import cmds print(cmds.about(p=True)) # import cgl.plugins.maya.userSetup module = importlib.import_module(module_name) func = getattr(module, func_name) ret.result = func(*args, **kwargs) except BaseException as e: # you have to do some funky stuff to pass a exception through pickle ret.exc = MayaStandAloneExceptionPickle(e, e.__traceback__) with open(result_file, 'wb') as f: pickle.dump(ret, f)
[docs] def run_in_maya_standalone(entrypoint, *args, **kwargs): """ run a function in maya standalone process and return result entrypoint is a string with following syntax: "cgl.plugins.maya.module_name:func_to_run" the ':' at the end is the function you want to run in the module args and kwargs need to be pickleable objects and as does the result of the function """ module_name, func_name = entrypoint.split(":") in_data = pickle.dumps([entrypoint, args, kwargs]) with tempfile.TemporaryDirectory() as tmp_dirname: result_file = os.path.join(tmp_dirname, "result").replace("\\", '/') cmd = [MAYAPY, '-c', f"from cgl.plugins.maya import standalone; standalone.main_maya('{result_file}');"] print(subprocess.list2cmdline(cmd)) proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE if unreal else None, stderr=subprocess.PIPE if unreal else None) out, err = proc.communicate(in_data) if proc.returncode: raise RuntimeError(f"Subprocess stderr:\n" + err.decode() if err else "") if not os.path.exists(result_file): raise RuntimeError("maya did not write a result file") with open(result_file, 'rb') as f: ret = pickle.load(f) if ret.exc: raise ret.exc return ret.result
if __name__ == "__main__": # r = run_in_maya_standalone("cgl.plugins.maya.standalone:test_func") r = run_in_maya_standalone("maya.cmds:sphere") print(r)