1
2 """ Inialize the mrv.maya sub-system and startup maya as completely as possible or configured """
3 import os, sys
4 import mrv
5 from mrv import init_modules
6 from mrv.util import capitalize, DAGTree, PipeSeparatedFile
7 from mrv.exc import MRVError
8 from mrv.path import make_path
9 from mrv.cmd.base import maya_to_py_version_map
10
11 from itertools import chain
12 import logging
13 log = logging.getLogger("mrv.maya")
14
15
16 if not hasattr( sys,"_dataTypeIdToTrackingDictMap" ):
17 sys._dataTypeIdToTrackingDictMap = dict()
18
19
20 __all__ = ("registerPluginDataTrackingDict", )
21
22
23
24
25
26
27
29 """Using the given dataTypeID and tracking dict, nt.PluginData can return
30 self pointers belonging to an MPxPluginData instance as returned by MFnPluginData.
31 Call this method to register your PluginData information to the mrv system.
32 Afterwards you can extract the self pointer using plug.masData().data()"""
33 sys._dataTypeIdToTrackingDictMap[ dataTypeID.id() ] = trackingDict
34
35
36
37
38
40 """This method should be called once a new maya release is encountered. It will
41 initialize and update the database as well as possible, and give instructions
42 on what to do next.
43
44 :note: Will not run if any user setup is performed as we need a clean maya
45 without any plugins loaded.
46 :raise EnvironmentError: if the current maya version has already been initialized
47 or if the user setup was executed"""
48 if int(os.environ.get('MRV_STANDALONE_AUTOLOAD_PLUGINS', 0)) or \
49 int(os.environ.get('MRV_STANDALONE_RUN_USER_SETUP', 0)):
50 raise EnvironmentError("Cannot operate if custom user setup was performed")
51
52
53 import env
54 import mdb
55
56 nodeshf = mdb.nodeHierarchyFile()
57 app_version = env.appVersion()[0]
58 if nodeshf.isfile():
59 raise EnvironmentError("Maya version %g already initialized as hierarchy file at %s does already exist" % (app_version, nodeshf))
60
61
62
63
64
65 mdb.writeMfnDBCacheFiles()
66
67
68
69
70
71
72 dagTree, typeToMFnList = mdb.generateNodeHierarchy()
73 dagTree.to_hierarchy_file('_root_', mdb.nodeHierarchyFile())
74
75
76
77 fp = open(mdb.cacheFilePath('nodeTypeToMfnCls', 'map'), 'wb')
78 mla = reduce(max, (len(t[0]) for t in typeToMFnList))
79 mlb = reduce(max, (len(t[1]) for t in typeToMFnList))
80
81 psf = PipeSeparatedFile(fp)
82 psf.beginWriting((mla, mlb))
83 for token in typeToMFnList:
84 psf.writeTokens(token)
85
86 fp.close()
87
88
89
90
91 print >> sys.stderr, "1. git status might reveals new MFnFunction sets as untracked files - check the new methods and possibly define aliases (or delete them wiht 'x')"
92 print >> sys.stderr, "2. Check the 'whats new' part of the maya docs for important API changes and possibly incorporate them into the code"
93 print >> sys.stderr, "3. run 'tmrv %g' and fix possibly breaking tests or the code being tested" % app_version
94 print >> sys.stderr, "4. run 'tmrvr' to assure all maya versions are still working - ideally on all platforms."
95 print >> sys.stderr, "5. run the UI tests and assure that they don't fail"
96 print >> sys.stderr, "6. Commit and push your changes - you are done"
97
98
99
100
101
103 """:return: DagTree from list of tuples [ (level,name),...], where level specifies
104 the level of items in the dag.
105 :note: there needs to be only one root node which should be first in the list
106 :return: `DagTree` item allowing to easily query the hierarchy """
107 tree = None
108 lastparent = None
109 lastchild = None
110 lastlevel = 0
111
112 for no,item in enumerate( tuplelist ):
113 level, name = item
114
115 if level == 0:
116 if tree != None:
117 raise MRVError( "DAG tree must currently be rooted - thus there must only be one root node, found another: " + name )
118 else:
119 tree = DAGTree( )
120 tree.add_node( name )
121 lastparent = name
122 lastchild = name
123 continue
124
125 direction = level - lastlevel
126 if direction > 1:
127 raise MRVError( "Can only change by one down the dag, changed by %i in item %s" % ( direction, str( item ) ) )
128
129 lastlevel = level
130 if direction == 0:
131 pass
132 elif direction == 1 :
133 lastparent = lastchild
134 elif direction == -1:
135 lastparent = tree.parent( lastparent )
136 elif direction < -1:
137 lastparent = list( tree.parent_iter( lastparent ) )[ -level ]
138
139 tree.add_edge( lastparent, name )
140 lastchild = name
141
142
143 return tree
144
146 """Create a tuple hierarchy list from the file at the given path
147 :return: tuple list suitable for dag_tree_from_tuple_list"""
148 lines = make_path( filepath ).lines( retain = False )
149
150 hierarchytuples = list()
151
152 for no,line in enumerate( lines ):
153 item = ( line.count( '\t' ), line.lstrip( '\t' ) )
154 hierarchytuples.append( item )
155
156 return hierarchytuples
157
158 -def initWrappers( mdict, types, metacreatorcls, force_creation = False ):
159 """ Create standin classes that will create the actual class once creation is
160 requested.
161 :param mdict: module dictionary object from which the latter classes will be imported from,
162 can be obtained using ``globals()`` in the module
163 :param types: iterable containing the names of classnames ( they will be capitalized
164 as classes must begin with a capital letter )"""
165 from mrv.maya.util import StandinClass
166
167
168 standin_instances = list()
169 for uitype in types:
170 clsname = capitalize( uitype )
171
172
173 if clsname in mdict:
174 continue
175
176 standin = StandinClass( clsname, metacreatorcls )
177 mdict[ clsname ] = standin
178
179 if force_creation:
180 standin_instances.append(standin)
181
182
183
184
185 for standin in standin_instances:
186 standin.createCls( )
187
189 """Move the maya vars as set in the shell into the os.environ to make them available to python"""
190 import maya.cmds as cmds
191 import subprocess
192 envcmd = "env"
193
194 if cmds.about( nt=1 ):
195 envcmd = "set"
196
197 p = subprocess.Popen( envcmd, shell=True, stdout=subprocess.PIPE )
198
199 for line in p.stdout:
200 try:
201 var,value = line.split("=", 1)
202 except:
203 continue
204 else:
205 os.environ[ var ] = value.strip()
206
207
208
209
210
211
212
213
214
215
216
218 """
219 Check if we are suited to import the maya namespace and try to set it
220 up such we can use the maya standalone package.
221 If running within maya or whith maya py, this is true, otherwise we have to
222 use the MAYA_LOCATION to get this to work.
223 """
224
225
226 binBaseName = os.path.split( sys.executable )[1].split( '.' )[0]
227 if binBaseName[0:4].lower() == 'maya' and binBaseName[0:6].lower() != 'mayapy':
228 return
229
230
231
232 locvar = 'MAYA_LOCATION'
233 if not os.environ.has_key( locvar ):
234 raise EnvironmentError( locvar + " was not set - it must point to the maya installation directory" )
235
236
237
238 mayalocation = os.path.realpath(os.environ[locvar])
239 splitpos = -1
240
241
242 if mayalocation.endswith( "Contents" ):
243 splitpos = -3
244
245 mayabasename = mayalocation.split( os.sep )[ splitpos ]
246
247
248 bits = 32
249 if mayabasename.endswith( '64' ):
250 bits = 64
251
252 mayabasename = mayabasename.replace( "-x64", "" )
253 mayaversion = mayabasename[4:]
254 fmayaversion = float(mayaversion)
255
256
257
258
259 pymayaversion = sys.version_info[0:2]
260 if len( mayaversion ):
261 pyminor = pymayaversion[1]
262
263 if float(mayaversion) not in maya_to_py_version_map:
264 raise EnvironmentError( "Requires Maya 8.5 or higher for python support, found " + mayaversion + " (or maya version is not implemented)" )
265
266 pyversion = pymayaversion[0] + (pymayaversion[1]/10.0)
267 if maya_to_py_version_map[float(mayaversion)] != pyversion:
268 raise EnvironmentError( "Maya " + mayaversion + " python interpreter requirements not met" )
269
270
271
272
273
274
275
276
277
278
279 for path in sys.path[:]:
280 if os.path.isdir(os.path.join(path, 'maya')) and not path.endswith("site-packages"):
281 sys.path.remove(path)
282
283
284
285
286
287 if os.name == "nt":
288 osspecific = os.path.join("Python", "lib")
289 else:
290 pyversionstr = str( pymayaversion[0] ) + "." + str( pymayaversion[1] )
291 osspecific = os.path.join("lib", "python" + pyversionstr, "site-packages")
292
293 mayapylibpath = os.path.join( mayalocation, osspecific, "site-packages" )
294 sys.path.append( mayapylibpath )
295
296
297
298
299 mrv._remove_empty_syspath_entries()
300
301 try:
302 import maya
303 except Exception, e:
304 print "Paths in sys.path: "
305 for p in sys.path: print "%r" % p
306 raise EnvironmentError( "Failed to import maya - check this script or assure LD_LIBRARY path is set accordingly: " + str( e ) )
307
308
309
310
311
312
313
314 try:
315 import maya.standalone
316 maya.standalone.initialize()
317 except:
318 log.debug("Paths in sys.path: ")
319 for p in sys.path: log.debug("%r" % p)
320 if 'maya' in locals():
321 log.info("Imported maya module is located at: %r" % maya.__file__)
322 log.error("ERROR: Failed initialize maya")
323 raise
324
325
326
327
328
329
330
331
332 if fmayaversion < 2009:
333 move_vars_to_environ( )
334
335
336 return
337
338
339
341 """Setup the path type to use slashes internally, no matter which operating
342 system we are on"""
343 import mrv.path
344 mrv.path.BasePath.set_separator('/')
345
347 """intiialize the user preferences according to the set configuration variables"""
348 try:
349 init_mel = int(os.environ.get('MRV_STANDALONE_INIT_OPTIONVARS', 0))
350 run_user_setup = int(os.environ.get('MRV_STANDALONE_RUN_USER_SETUP', 0))
351 autoload_plugins = int(os.environ.get('MRV_STANDALONE_AUTOLOAD_PLUGINS', 0))
352 except ValueError, e:
353 log.warn("Invalid value for MRV configuration variable: %s" % str(e).split(':', 1)[-1])
354
355
356 def source_file_safely(script):
357 try:
358 maya.mel.eval('source "%s"' % script)
359 except RuntimeError, e:
360 log.error(str(e) + "- ignored")
361
362
363
364 if not (init_mel|run_user_setup|autoload_plugins):
365 return
366
367 import maya.cmds as cmds
368 prefsdir = make_path(cmds.internalVar(userPrefDir=1))
369
370 if not prefsdir.isdir():
371 log.warn("User Preferences directory did not exist: %s" % prefsdir)
372 return
373
374
375
376 sources = list()
377 if init_mel:
378 sources.append("createPreferencesOptVars.mel")
379 sources.append("createGlobalOptVars.mel")
380 sources.append(prefsdir + "/userPrefs.mel")
381
382
383 if autoload_plugins:
384 sources.append(prefsdir + "/pluginPrefs.mel")
385
386
387
388 import maya.mel
389 for scriptpath in sources:
390 if os.path.isabs(scriptpath) and not os.path.isfile(scriptpath):
391 log.warn("Couldn't source %s as it did not exist" % scriptpath)
392
393
394 source_file_safely(scriptpath)
395
396
397 if run_user_setup:
398
399 source_file_safely("userSetup.mel")
400
401
402
403
404
415
416
418 """Assure that logging can print to stdout and stderr which get overwritten
419 by special maya versions which lack the 'flush' method"""
420
421 class PassOnOrDummy(object):
422 def __init__(self, obj):
423 self.obj = obj
424
425 def does_nothing(self, *args, **kwargs):
426 return
427
428 def __getattr__(self, attr):
429 try:
430 return getattr(self.obj, attr)
431 except AttributeError:
432 return self.does_nothing
433
434
435
436 for channame in ('stdout', 'stderr'):
437 chan = getattr(sys, channame)
438 if hasattr(chan, 'flush'):
439 continue
440
441
442
443 fixedchan = PassOnOrDummy(chan)
444 setattr(sys, channame, fixedchan)
445
446
447 for l in chain((logging.root, ), logging.root.manager.loggerDict.values()):
448 if not isinstance(l, logging.Logger):
449 continue
450
451 for handler in l.handlers:
452 if isinstance(handler, logging.StreamHandler) and handler.stream is chan:
453 handler.stream = fixedchan
454
455
456
457
458
459
460
461
462 if 'init_done' not in locals():
463 init_done = False
464
465
466 if not init_done:
467
468 init_system()
469 init_path()
470 init_standard_output()
471 init_modules(__file__, "mrv.maya")
472 init_singletons()
473
474
475 init_done = True
476 init_user_prefs()
477