1
2 '''
3 A module for building pyMaya jobs.
4
5 These jobs use a persistent Maya instance on the farm; a Dynamic Allocation jobtype.
6 '''
7
8
9
10
11
12 import sys
13 import os
14
15 try:
16 import qb
17 except:
18 if 'QBDIR' in os.environ:
19 QBDIR = os.environ['QBDIR']
20 else:
21 if os.name == 'posix':
22 if os.uname()[0] == 'Darwin':
23 QBDIR = '/Applications/pfx/qube'
24 else:
25 QBDIR = '/usr/local/pfx/qube'
26
27 sys.path.append('%s/api/python' % QBDIR)
28 import qb
29
30 try:
31 from qb import frontend
32 from qb.frontend import pythonFrontEnd as pythonFrontEnd
33 except ImportError:
34 from AppUI import frontend
35 from AppUI.frontend import pythonFrontEnd as pythonFrontEnd
36
37
39 - def __init__(self, mayaExe, mayaArgs=None, dev=False):
40 """
41 Function to initialize members of the class
42
43 @param mayaExe: path to executable or script to start maya's python prompt
44 @type mayaExe: C{str}
45
46 @param mayaArgs: Optional arguments to use when starting the Maya python session.
47 @type mayaArgs: C{dict}
48
49 @param dev: Set the 'dev' value for the Qube job, enables debug output on the farm.
50 @type dev: bool
51 """
52 super(MayaPythonJob, self).__init__(dev=dev)
53
54 self['kind'] = 'maya'
55 self['prototype'] = 'pyMaya'
56
57 pkg = {
58 'pyExecutable': mayaExe,
59 'mayaArgs': mayaArgs,
60 'regex_errors': 'License failure',
61 'smartAgenda': 1
62 }
63 self['package'].update(pkg)
64
65 self['package']['regex_errors'] = '\n'.join(
66 ['License failure',
67 'Can\'t read .* No such file or directory'])
68
69 self['package']['regex_highlights'] = '\n'.join(
70 ['^Licence expires on.*']
71 )
72
73 self.addJobCmds('print "Maya version: %s " % mc.about(v=True)')
74 self['agenda'] = []
75
76
78
79 MAYA_IMAGE_FORMAT_INTS = {
80 'tif': 3,
81 'iff': 7,
82 'jpg': 8,
83 'tga': 19
84 }
85
86 - def __init__(self, mayaExe, scenefile, frameRange, mayaArgs=None,
87 imgFormat='tif', renderCam='persp', renderer='mayaSoftware',
88 jobName='', jobLabel='', dev=False):
89 """
90 Function to initialize members of the class
91
92 @param frameRange: A frame range string. 1-3,6-10x2 expands to [1,2,3,6,8,10]
93 @type frameRange: C{str}
94
95 @param scenefile: The full disk path to a Maya scenefile
96 @type scenefile: C{str}
97
98 @param mayaArgs: Optional arguments to use when starting the Maya python session.
99 @type mayaArgs: C{dict}
100
101 @param jobName: Optional qube job name
102 @type jobName: C{str}
103
104 @param jobLabel: Optional qube job label
105 @type jobLabel: C{str}
106
107 @param dev: Set the 'dev' value for the Qube job, enables debug output on the farm.
108 @type dev: bool
109 """
110 super(MayaRenderJob, self).__init__(mayaExe, mayaArgs=mayaArgs, dev=dev)
111
112 self['package']['scenefile'] = scenefile
113 (scenefile, scriptExt) = os.path.splitext(os.path.basename(self['package']['scenefile']))
114
115 self['package']['frameRange'] = frameRange
116 self['package']['smartAgenda'] = True
117
118 self['package']['imgFormat'] = imgFormat
119 self['package']['renderCam'] = renderCam
120 self['package']['renderer'] = renderer
121
122 if jobName:
123 self['name'] = jobName
124 else:
125 self['name'] = 'Maya render %s%s' % (scenefile, scriptExt)
126
127 if jobLabel:
128 self['label'] = jobLabel
129
130 self['package']['regex_outputPaths'] = 'Finished Rendering (.*)'
131
132 self.addJobCmds('scenefile = mc.file("%%s" %% os.path.normpath("%s"), open=True, force=True)' % self['package']['scenefile'])
133
134 self['agenda'] = self._buildAgenda()
135
136
138 '''
139 Create an agenda for the job, complete with per-frame python commands.
140
141 @return: The populated work agenda for the job
142 @rtype: C{dict}
143 '''
144 agenda = []
145
146 for item in qb.genframes(self['package']['frameRange']):
147 cmds = []
148
149 cmds.append('mc.currentTime(%s)' % item['name'])
150 cmds.append("mc.setAttr('defaultRenderGlobals.startFrame', %s)" % item['name'])
151 cmds.append("mc.setAttr('defaultRenderGlobals.endFrame', %s)" % item['name'])
152 cmds.append('mc.render("%s")' % self['package']['renderCam'])
153
154 item['package'] = {'commands': cmds}
155
156 agenda.append(item)
157
158 return agenda
159
160 if __name__ == '__main__':
161 '''
162 A "hello world", meant to show how to build and submit a Maya dynamic allocation job using the pythonChildJob framework.
163 '''
164
165
166
167 jobList = []
168
169
170 mayaExe= 'C:/Program Files/Autodesk/Maya2015/bin/mayapy.exe'
171
172 mayaExe = '//NEWTON/Pypeline/bin/current/win/mayapy.bat'
173 mayaExe = '//NEWTON/Pypeline/bin/current/all/mayapy.py'
174 mayaExe = '//NEWTON/Pypeline/bin/current/all/mayapy_.bat'
175
176 mayaArgs = []
177
178 jobA = MayaPythonJob(mayaExe, mayaArgs=mayaArgs)
179 jobA['cpus'] = 1
180 jobA['name'] += 'maya hello world'
181
182
183
184 scene = '//eru/PY_DEV/episodes/ep01/seq_010/seq_010_001/workspace/animation/pipeline/maya/scenes/no_spaces.ma'
185 frange = '1-20'
186 jobB = MayaRenderJob(mayaExe, scene, frange)
187 jobB['cpus'] = 1
188 jobB['max_cpus'] = -1
189
190 jobB['reservations'] = 'host.processors=1+'
191 jobList.append(jobB)
192
193 if '--arc' in sys.argv:
194 arcSize = qb.archivejob('job.qja', jobB, format=qb.QB_API_BINARY)
195 print 'job.qja: %s bytes' % arcSize
196 else:
197 for j in qb.submit(jobList):
198 print 'submitted: %(id)s' % j
199