def makeScriptPathRelative( scriptFilepath ): ''' will attempt to transform the name of the given script into the shortest possible path relative to the python search paths defined in sys.path. For example, just say you have a package called "foo" this package contains the script: "bar.py" given the full path to bar.py this function will return: "foo/bar.py" ''' scriptFilepath = Path( scriptFilepath ) sysPaths = map( Path, sys.path ) bestFitPath = None for p in sysPaths: if scriptFilepath.isUnder( p ) or len( p ) > len( bestFitPath ): if bestFitPath is None: bestFitPath = p if bestFitPath is None: raise ValueError( "Cannot find a path under any of the paths in sys.path!" ) shortestPath = scriptFilepath - bestFitPath return shortestPath
def setupZooToolBox(): #all the files for zooToolBox should live in the same directory as this script, including plug-ins thisFile = Path( __file__ ) thisPath = thisFile.up() existingPlugPathStr = maya.mel.eval( 'getenv MAYA_PLUG_IN_PATH;' ) existingPlugPaths = existingPlugPathStr.split( ';' ) newPlugPaths = [] pathsAlreadyInList = set() zooPlugPathAdded = False for path in existingPlugPaths: path = Path( path ) if path in pathsAlreadyInList: continue pathsAlreadyInList.add( path ) newPlugPaths.append( path.unresolved() ) if path == thisPath: zooPlugPathAdded = True if not zooPlugPathAdded: newPlugPaths.append( thisPath ) newPlugPathStr = ';'.join( newPlugPaths ) maya.mel.eval( 'putenv MAYA_PLUG_IN_PATH "%s";' % newPlugPathStr ) #now setup the dagMenuProc setupDagProcMenu()
def packageScripts( scriptFilesToPackage, destPackageFilepath, dependencyTree ): ''' will package all given files and import dependencies into a single zip file ''' destPackageFilepath = Path( destPackageFilepath ).setExtension( 'zip' ) if destPackageFilepath.exists: destPackageFilepath.delete() filesToPackage = map( Path, scriptFilesToPackage ) for f in scriptFilesToPackage: filesToPackage += dependencyTree.findDependencies( f, None, False ) if not filesToPackage: return None #remove any duplicate files... filesToPackage = removeDupes( filesToPackage ) #this is a little hacky - but we don't want to re-distribute wingdbstub so lets check to see if its in the list of files for f in filesToPackage: if f.name() == 'wingdbstub': filesToPackage.remove( f ) break #now build the zip file import zipfile with zipfile.ZipFile( str( destPackageFilepath ), 'w' ) as thePackage: for f in filesToPackage: thePackage.write( str( f ), str( makeScriptPathRelative( f ) ) ) return destPackageFilepath
def isScriptInSuperiorBranch( scriptPath ): ''' returns whether the given scriptPath can be found in a directory searched before the given script. Ie, if the following paths are in sys.path: sys.path = [ 'd:/somePath', 'd:/otherPath' ] isScriptInSuperiorBranch( 'd:/otherPath/someScript.py' ) if there is a someScript.py in d:/somePath, this function will return True ''' if not isinstance( scriptPath, Path ): scriptPath = Path( scriptPath ) originalPath = scriptPath for p in sys.path: if scriptPath.isUnder( p ): scriptPath = scriptPath - p break for p in sys.path: possibleSuperiorPath = p / scriptPath if possibleSuperiorPath.exists: if possibleSuperiorPath == originalPath: return None return possibleSuperiorPath
def build_popup(self, parent, *a): cmd.setParent(parent, m=True) cmd.menu(parent, e=True, dai=True) thisFile = Path(cmd.file(q=True, sn=True)) #if the file doesn't exist, then use teh cwd if not thisFile.exists: thisFile = thisFile.getcwd() / "tmp.ma" dir = thisFile.up() curFile = Path(cmd.textField(self.UI_file, q=True, tx=True)) for f in dir.files(): if f.hasExtension(skinWeights.EXTENSION): cmd.menuItem(l=f.name(), cb=f == curFile, c=api.Callback(cmd.textField, self.UI_file, e=True, tx=f)) cmd.menuItem(d=True) cmd.menuItem(l="browse", c=self.on_browseWeightFile) cmd.menuItem(d=True) cmd.menuItem(l="clear", c=lambda *a: cmd.textField(self.UI_file, e=True, tx='')) if curFile.exists: cmd.menuItem(d=True) api.addExploreToMenuItems(curFile)
def getControlShapeFiles(): dir = CONTROL_DIRECTORY if isinstance(dir, basestring): dir = Path(dir) if not isinstance(dir, Path) or not dir.exists: dir = Path(__file__).up() shapes = [] if dir.exists: shapes = [f for f in dir.files() if f.hasExtension('shape')] if not shapes: searchPaths = map(Path, sys.path) searchPaths += map(Path, os.environ.get('MAYA_SCRIPT_PATH', '').split(';')) searchPaths = removeDupes(searchPaths) for d in searchPaths: try: shapes += [f for f in d.files() if f.hasExtension('shape')] except WindowsError: continue return shapes
def _iterRigPartScripts(): for p in sys.path: p = Path(p) if 'maya' in p: # for f in p.files(): if f.hasExtension('py'): if f.name().startswith(RIG_PART_SCRIPT_PREFIX): yield f
def _iterSkeletonPartScripts(): for p in sys.path: p = Path(p) if 'maya' in p: for f in p.files(): if f.hasExtension('py'): if f.name().startswith(SKELETON_PART_SCRIPT_PREFIX): yield f
def _iterSkeletonPartScripts(): for p in sys.path: p = Path( p ) if 'maya' in p: for f in p.files(): if f.hasExtension( 'py' ): if f.name().startswith( SKELETON_PART_SCRIPT_PREFIX ): yield f
def _iterRigPartScripts(): for p in sys.path: p = Path( p ) if 'maya' in p: # for f in p.files(): if f.hasExtension( 'py' ): if f.name().startswith( RIG_PART_SCRIPT_PREFIX ): yield f
def getFileStr( self, f=None, allowMultiple=False, verifyExistence=True ): if f is None: return '"%s"' % self if isinstance( f, (list, tuple) ): if verifyExistence: return '"%s"' % '" "'.join( [ anF for anF in f if Path( anF ).exists ] ) else: return '"%s"' % '" "'.join( f ) return '"%s"' % Path( f )
def load_module( self, fqname, fp, pathname, file_info ): if pathname: if not isinstance( pathname, Path ): pathname = Path( pathname ) if pathname.hasExtension( 'cmd' ): line = fp.readline().strip() suffix, mode, type = file_info[0], file_info[1], imp.PY_SOURCE #pretend the cmd script is a py file assert '@setlocal' in line and '& python' in line, "Doesn't seem to be a python cmd script!" return ModuleFinder.load_module( self, fqname, fp, pathname, file_info )
def __new__(cls, dirsToWalk=(), dirsToExclude=(), extraSearchPaths=(), rebuildCache=False, skipLib=True): ''' constructs a new dependencyTree dictionary or loads an existing one from a disk cache, and strips out files that no longer exist ''' if not dirsToWalk: dirsToWalk = sys.path[:] dirsToWalk = map(Path, dirsToWalk) dirsToExclude = map(Path, dirsToExclude) if skipLib: dirsToExclude += _LIB_PATHS cache = Path(cls._CACHE_PATH) self = None if cache.exists() and not rebuildCache: try: with file(cache, 'r') as f: version, self = pickle.load(f) except: pass else: if version == cls._VERSION: cls.FromSimpleDict( self ) #keys are converted to strings before pickling - so convert them back to Path instances cls.FromSimpleDict(self._crcs) cls.FromSimpleDict(self._stats) #remove any files from the cache that don't exist for f in self.keys(): if not f.exists(): self.pop(f) else: self = None logWarning('VERSION UPDATE: forcing rebuild') if self is None: self = dict.__new__(cls) self._crcs = {} self._stats = {} self._dirs = dirsToWalk self._dirsExclude = dirsToExclude self._extraPaths = extraSearchPaths self.freshenDependencies() return self
def setValue( self, value, executeChangeCB=False ): ''' the value we recieve should be a fullpath - but we want to store is as a scene relative path ''' value = Path( value ) #make sure it is actually an absolute path... if value.isAbs(): curSceneDir = Path( cmd.file( q=True, sn=True ) ).up() value = value - curSceneDir self.UI_filepath.setValue( value, executeChangeCB )
def populateTestScripts(): global TEST_SCRIPTS thisScriptDir = Path(__file__).up() pathsToSearch = sys.path[:] + [thisScriptDir] for pyPath in pathsToSearch: pyPath = Path(pyPath) if pyPath.isDir(): for f in pyPath.files(): if f.hasExtension('py'): if f.name().startswith('devTest_'): TEST_SCRIPTS[f] = []
def on_browse( self, *a ): curValue = self.getValue() ext = curValue.getExtension() or 'txt' if curValue.isFile(): curValue = curValue.up() elif not curValue.isDir(): curValue = Path( cmd.file( q=True, sn=True ) ).up( 2 ) if not curValue.exists(): curValue = Path( '' ) filepath = cmd.fileDialog( directoryMask=curValue / ("/*.%s" % ext) ) if filepath: self.setValue( filepath, True )
def on_dirChange( self, theDir=None ): if theDir is None: theDir = self.getDir() theDir = Path( theDir ) self.UI_files.setRootDir( theDir ) self.populateFiles()
def writePresetToFile( presetFilepath ): try: contents = generatePresetContents() except NoPartsError: print "No parts found in the scene!" return Path( presetFilepath ).write( contents )
def __new__( cls, dirsToWalk=(), dirsToExclude=(), extraSearchPaths=(), rebuildCache=False, skipLib=True ): ''' constructs a new dependencyTree dictionary or loads an existing one from a disk cache, and strips out files that no longer exist ''' if not dirsToWalk: dirsToWalk = sys.path[:] dirsToWalk = map( Path, dirsToWalk ) dirsToExclude = map( Path, dirsToExclude ) if skipLib: dirsToExclude += _LIB_PATHS cache = Path( cls._CACHE_PATH ) self = None if cache.exists() and not rebuildCache: try: with file( cache, 'r' ) as f: version, self = pickle.load( f ) except: pass else: if version == cls._VERSION: cls.FromSimpleDict( self ) #keys are converted to strings before pickling - so convert them back to Path instances cls.FromSimpleDict( self._crcs ) cls.FromSimpleDict( self._stats ) #remove any files from the cache that don't exist for f in self.keys(): if not f.exists(): self.pop( f ) else: self = None logWarning( 'VERSION UPDATE: forcing rebuild' ) if self is None: self = dict.__new__( cls ) self._crcs = {} self._stats = {} self._dirs = dirsToWalk self._dirsExclude = dirsToExclude self._extraPaths = extraSearchPaths self.freshenDependencies() return self
def findDependents( self, changedScriptPath ): ''' returns a 2-tuple of scripts that immediately rely on changedScriptPath. ie: the scripts that directly import the queried script, and those that import the queried script by proxy. Secondary scripts are any downstream script that imports the one in question - regardless of how far down the dependency chain it is. ie: given scriptA, scriptB, scriptC scriptA imports scriptB scriptB imports scriptC calling findDependents( scriptC ) will return scriptB as an immediate dependent, and scriptA as a secondary dependent ''' changedScriptPath = Path( changedScriptPath ) #make sure the script in question doesn't have a superior script hasSuperior = isScriptInSuperiorBranch( changedScriptPath ) if hasSuperior is not None: logWarning( 'WARNING - a superior script was found: %s. Using it for dependency query instead!' % hasSuperior ) changedScriptPath = hasSuperior primaryAffected = set() secondaryAffected = set() #add the primary affected dependencies for script, depNode in self.iteritems(): if script == changedScriptPath: continue #if the changedScript is in this dependency node, add the script to the list of affected if changedScriptPath in depNode: primaryAffected.add( script ) #don't even start looking for secondary deps if there are no primary deps... if primaryAffected: #returns whether it has found any new dependencies def gatherSecondaryDependencies( theDepNode ): stillAdding = False for script, depNode in theDepNode.iteritems(): if script == changedScriptPath: continue if script in primaryAffected or script in secondaryAffected: continue #if its not, we had better recurse and see if it is somewhere deeper in the dependency tree for this script else: for sub_script in depNode.iterkeys(): if sub_script in primaryAffected or sub_script in secondaryAffected: secondaryAffected.add( script ) stillAdding = True return stillAdding #keep calling gatherSecondaryDependencies until it returns False while gatherSecondaryDependencies( self ): pass return primaryAffected, secondaryAffected
def on_storeB(self, *a): kw = {} if self.UI_file.getValue(): kw['filepath'] = Path(self.UI_file.getValue()) joints = cmd.ls(type='joint', r=True) jointMeshes = removeDupes( cmd.listRelatives(joints, ad=True, pa=True, type='mesh')) skinWeights.saveWeights(jointMeshes, **kw)
def getDefaultPath( filepath, dmeMesh=None ): if filepath is None: if dmeMesh is None: raise SkinWeightException fileId = dmeMesh.GetFileId() fileRoot = vs.dm.GetElement( vs.dm.GetFileRoot( fileId ) ) fileName = Path( vs.dm.GetFileName( fileId ) ) srcFile = Path( fileRoot.makefile.sources[ 0 ].name ) filepath = fileName.up() / srcFile #filepath = vs.dm.GetFileName( dmeMesh.GetFileId() ) filepath = Path( filepath ) if not filepath.exists: raise SkinWeightException filepath = filepath.setExtension( EXTENSION ) return filepath
def on_buildRig( self, e=None ): autoFinalize = True curScene = Path( cmd.file( q=True, sn=True ) ) referenceModel = self.UI_reference.getValue() if referenceModel: if not curScene: api.doConfirm( t='Scene not saved!', m="Looks like your current scene isn't saved\n\nPlease save it first so I know where to save the rig. thanks!", b=('OK',), db='OK' ) return rigPrimitives.buildRigForModel( None, autoFinalize, referenceModel )
def addDepedency( self, callerScriptPaths ): curDepNode = self for callScript in callerScriptPaths[ 1: ]: #skip the first item - its always the script being walked for dependencies #builtins have None for their paths as do modules in the stdlib if they're in a zip file, so break #because at this point we don't care about downstream deps because we don't change the stdlib if callScript is None: break curDepNode = curDepNode.setdefault( Path( callScript ), DependencyNode() ) return curDepNode
def setupZooToolBox(): #all the files for zooToolBox should live in the same directory as this script, including plug-ins thisFile = Path(__file__) thisPath = thisFile.up() existingPlugPathStr = maya.mel.eval('getenv MAYA_PLUG_IN_PATH;') existingPlugPaths = existingPlugPathStr.split(';') newPlugPaths = [] pathsAlreadyInList = set() zooPlugPathAdded = False for path in existingPlugPaths: path = Path(path) if path in pathsAlreadyInList: continue pathsAlreadyInList.add(path) newPlugPaths.append(path.unresolved()) if path == thisPath: zooPlugPathAdded = True if not zooPlugPathAdded: newPlugPaths.append(thisPath) newPlugPathStr = ';'.join(newPlugPaths) maya.mel.eval('putenv MAYA_PLUG_IN_PATH "%s";' % newPlugPathStr) #now setup the dagMenuProc setupDagProcMenu()
def getControlShapeFiles(): dir = CONTROL_DIRECTORY if isinstance( dir, basestring ): dir = Path( dir ) if not isinstance( dir, Path ) or not dir.exists: dir = Path( __file__ ).up() shapes = [] if dir.exists: shapes = [ f for f in dir.files() if f.hasExtension( 'shape' ) ] if not shapes: searchPaths = map( Path, sys.path ) searchPaths += map( Path, os.environ.get( 'MAYA_SCRIPT_PATH', '' ).split( ';' ) ) searchPaths = removeDupes( searchPaths ) for d in searchPaths: try: shapes += [ f for f in d.files() if f.hasExtension( 'shape' ) ] except WindowsError: continue return shapes
def loadPostTraceSchemeFilepath( presetFile ): ''' re-applies a stored post trace command scheme back to the controls found in the current scene ''' #first we need to purge all existing post trace commands clearPostTraceScheme() if not isinstance( presetFile, Path ): presetFile = Path( presetFile ) if not presetFile.isfile(): raise IOError, "no such preset" xportDict, postTraceDict = presetFile.unpickle() for n, postTraceCmd in postTraceDict.iteritems(): n = n.split( '.' )[ 0 ] #strip off the attribute possibles = cmd.ls( '*%s' % n, r=True ) if possibles: nInScene = possibles[0] api.mel.zooSetPostTraceCmd( nInScene, postTraceCmd )
def findDependencies(self, scriptPath, depth=None, includeFilesFromExcludedDirs=True): ''' returns a list of dependencies for scriptPath ''' scriptPath = Path(scriptPath) #make sure the script in question doesn't have a superior script hasSuperior = isScriptInSuperiorBranch(scriptPath) if hasSuperior is not None: logWarning( 'WARNING - a superior script was found: %s. Using it for dependency query instead!' % hasSuperior) scriptPath = hasSuperior deps = set() maxDepth = depth def getDeps(script, depth=0): if maxDepth is not None and depth >= maxDepth: return if script in self: for ss in self[script]: if ss in deps: continue deps.add(ss) getDeps(ss, depth + 1) getDeps(scriptPath) #if we're not including files from excluded directories, go through the list of deps and remove files that are under any of the exlude dirs if not includeFilesFromExcludedDirs: depsWithoutExcludedFiles = [] for dep in deps: shouldFileBeIncluded = True for excludeDir in self._dirsExclude: if dep.isUnder(excludeDir): shouldFileBeIncluded = False break if shouldFileBeIncluded: depsWithoutExcludedFiles.append(dep) deps = depsWithoutExcludedFiles return list(sorted(deps))
def runTestCases(testCases=TEST_CASES): thisPath = Path(__file__).up() testResults = TestResult() reloadedTestCases = [] for test in testCases: #find the module the test comes from module = inspect.getmodule(test) performReload = getattr(module, 'PERFORM_RELOAD', True) #reload the module the test comes from if performReload: module = reload(module) #find the test object inside the newly re-loaded module and append it to the reloaded tests list reloadedTestCases.append(getattr(module, test.__name__)) for ATestCase in reloadedTestCases: testCase = ATestCase() testCase.run(testResults) #force a new scene cmd.file(new=True, f=True) OK = 'Ok' BUTTONS = (OK, ) if testResults.errors: print '------------- THE FOLLOWING ERRORS OCCURRED -------------' for error in testResults.errors: print error[0] print error[1] print '--------------------------' cmd.confirmDialog( t='TEST ERRORS OCCURRED!', m= 'Errors occurred running the tests - see the script editor for details!', b=BUTTONS, db=OK) else: print '------------- %d TESTS WERE RUN SUCCESSFULLY -------------' % len( testCases) cmd.confirmDialog(t='SUCCESS!', m='All tests were successful!', b=BUTTONS, db=OK) return testResults
def convexifyObjects(objs): noUndo = vs.CDisableUndoScopeGuard() dmxedit = vs.dmxedit tmpFile = Path('%TEMP%/tmp.dmx') cmd.vsdmxio(objs, export=True, sl=True, ascii=True, filename=tmpFile) #now load the file root = dmxedit.LoadDmx(tmpFile) for dag in root.model.dagWalk(): shape = dag.shape if isinstance(shape, vs.movieobjects.CDmeMesh): convexHull = dmxedit.ComputeConvexHull3D(shape) convexHull.name = dag.name dag.SetShape(convexHull) dmxedit.SaveDmx(root, tmpFile) importedNodes = cmd.vsdmxio(i=True, filename=tmpFile) tmpFile.delete() toReturn = [] toDelete = set() for n in importedNodes: if cmd.nodeType(n) == 'mesh': p = cmd.listRelatives(n, pa=True, p=True)[0] pp = cmd.listRelatives(p, pa=True, p=True)[0] toDelete.add(pp) p = cmd.parent(p, world=True)[0] p = cmd.rename(p, n.split('|')[-1]) toReturn.append(p) cmd.delete(list(toDelete)) return toReturn
def convexifyObjects( objs ): noUndo = vs.CDisableUndoScopeGuard() dmxedit = vs.dmxedit tmpFile = Path( '%TEMP%/tmp.dmx' ) cmd.vsdmxio( objs, export=True, sl=True, ascii=True, filename=tmpFile ) #now load the file root = dmxedit.LoadDmx( tmpFile ) for dag in root.model.dagWalk(): shape = dag.shape if isinstance( shape, vs.movieobjects.CDmeMesh ): convexHull = dmxedit.ComputeConvexHull3D( shape ) convexHull.name = dag.name dag.SetShape( convexHull ) dmxedit.SaveDmx( root, tmpFile ) importedNodes = cmd.vsdmxio( i=True, filename=tmpFile ) tmpFile.delete() toReturn = [] toDelete = set() for n in importedNodes: if cmd.nodeType( n ) == 'mesh': p = cmd.listRelatives( n, pa=True, p=True )[ 0 ] pp = cmd.listRelatives( p, pa=True, p=True )[ 0 ] toDelete.add( pp ) p = cmd.parent( p, world=True )[ 0 ] p = cmd.rename( p, n.split( '|' )[ -1 ] ) toReturn.append( p ) cmd.delete( list( toDelete ) ) return toReturn
def getFiles( self ): files = [] for d in self._dirs: skipDir = False for dd in self._dirsExclude: if d.isUnder( dd ): skipDir = True break if skipDir: continue for dirPath, dirNames, fileNames in os.walk( d ): dirPath = Path( dirPath ) skipDir = False for d in self._dirsExclude: if dirPath.isUnder( d ): skipDir = True break if skipDir: continue for f in fileNames: f = dirPath / f if f.hasExtension( 'py' ): files.append( f ) #if the cmd script looks like its a python cmd script, then add it to the list - the DepFinder class knows how to deal with these files elif f.hasExtension( 'cmd' ): with file( f ) as fopen: line = fopen.readline().strip() if '@setlocal ' in line and '& python' in line: files.append( f ) return files
def on_restore(self, *a): filepath = None if self.UI_file.getValue(): filepath = Path(self.UI_file.getValue()) skinWeights.loadWeights( cmd.ls(sl=True), filepath, True, #not self.UI_restoreById.getValue(), self.UI_ratio.getValue(), (-1, ) if self.UI_mirror.getValue() else None, averageVerts=self.UI_average.getValue(), doPreview=False, #self.UI_doPreview.getValue(), meshNameRemapDict=self.getMeshRemapDict(), jointNameRemapDict=self.getJointRemapDict())
def build_popup( self, parent, *a ): cmd.setParent( parent, m=True ) cmd.menu( parent, e=True, dai=True ) thisFile = Path( cmd.file( q=True, sn=True ) ) #if the file doesn't exist, then use teh cwd if not thisFile.exists: thisFile = thisFile.getcwd() / "tmp.ma" dir = thisFile.up() curFile = Path( cmd.textField( self.UI_file, q=True, tx=True ) ) for f in dir.files(): if f.hasExtension( skinWeights.EXTENSION ): cmd.menuItem( l=f.name(), cb=f==curFile, c=api.Callback( cmd.textField, self.UI_file, e=True, tx=f ) ) cmd.menuItem( d=True ) cmd.menuItem( l="browse", c=self.on_browseWeightFile ) cmd.menuItem( d=True ) cmd.menuItem( l="clear", c=lambda *a: cmd.textField( self.UI_file, e=True, tx='' ) ) if curFile.exists: cmd.menuItem( d=True ) api.addExploreToMenuItems( curFile )
def FetchByNumber( cls, number ): lines = _p4run( '-s', 'describe', number ) if not lines: return None change = cls() change.change = number change.description = '' lineIter = iter( lines[ 2: ] ) try: prefix = 'text:' PREFIX_LEN = len( prefix ) line = lineIter.next() while line.startswith( prefix ): line = line[ PREFIX_LEN: ].lstrip() if line.startswith( 'Affected files ...' ): break change.description += line line = lineIter.next() prefix = 'info1:' PREFIX_LEN = len( prefix ) while not line.startswith( prefix ): line = lineIter.next() while line.startswith( prefix ): line = line[ PREFIX_LEN: ].lstrip() idx = line.rfind( '#' ) depotFile = Path( line[ :idx ] ) revAndAct = line[ idx + 1: ].split() rev = int( revAndAct[ 0 ] ) act = revAndAct[ 1 ] change.files.append( depotFile ) change.actions.append( act ) change.revisions.append( rev ) line = lineIter.next() except StopIteration: pass return change
def _getDeps( module ): #grab module dependencies for n, o in aModule.__dict__.iteritems(): try: objectFile = Path( getfile( o ) ) #this happens on builtins... so skip em except TypeError: continue if isinstance( o, _MODULE_TYPE ): if objectFile in dependencySet: continue dependencySet.add( objectFile ) _getDeps( o ) #recurse else: dependencySet.add( objectFile )
def setupDagProcMenu(): ''' sets up the modifications to the dagProcMenu script ''' dagMenuScript = r'C:\Program Files\Autodesk\Maya2011\scripts\others\dagMenuProc.mel' globalProcDefRex = re.compile( "^global +proc +dagMenuProc *\( *string *(\$[a-zA-Z0-9_]+), *string *(\$[a-zA-Z0-9_]+) *\)" ) dagMenuScriptLines = Path(dagMenuScript).read() dagMenuScriptLineIter = iter(dagMenuScriptLines) newLines = [] hasDagMenuProcBeenSetup = False for line in dagMenuScriptLineIter: newLines.append(line) globalProcDefSearch = globalProcDefRex.search(line) if globalProcDefSearch: parentVarStr, objectVarStr = globalProcDefSearch.groups() selHierarchyRex = re.compile( 'uiRes *\( *"m_dagMenuProc.kSelectHierarchy" *\)') #menuItem -label (uiRes("m_dagMenuProc.kDagMenuSelectHierarchy")) -c ("select -hierarchy " + $object); #if we're past the global proc definition for dagMenuProc start looking for the menu item to for line in dagMenuScriptLineIter: newLines.append(line) if 'menuItem' in line and selHierarchyRex.search(line): newLines.append('\t\t\tmenuItem -d 1;') newLines.append('\t\t\tpython( "import triggeredUI" );') newLines.append( """\t\t\tint $killState = python( "triggeredUI.buildMenuItems( '"+ %s +"', '"+ %s +"' )" );""" % (parentVarStr, objectVarStr)) newLines.append('\t\t\tif( $killState ) return;') hasDagMenuProcBeenSetup = True break if not hasDagMenuProcBeenSetup: printErrorStr("Couldn't auto setup dagMenuProc! AWOOGA!") return newScript = '\n'.join(newLines) evalMel(newScript)
def on_buildRig( self, e=None ): curScene = Path( cmd.file( q=True, sn=True ) ) referenceModel = self.UI_reference.getValue() if referenceModel: if not curScene: cmd.confirmDialog( t='Scene not saved!', m="Looks like your current scene isn't saved\n\nPlease save it first so I know where to save the rig. thanks!", b=('OK',), db='OK' ) return rigPrimitives.buildRigForModel( referenceModel=referenceModel, deletePlacers=False ) #if the model is being referenced run populate to update the rig part instances - container names will have changed because they're now referenced if referenceModel: self.populate() #if we're not referencing the model however, its safe to just run the updateBuildRigButton method on all rig part UI instances else: for partUI in self.UI_partForms: partUI.updateBuildRigButton()
def propagateWeightChangesToModel( meshes ): ''' Given a list of meshes to act on, this function will store the skin weights, remove any edits from the skin clusters that affect them, open the scene file the meshes come from and apply the weights to the geometry in that scene. This makes it possible to fix skinning problems while animating with minimal workflow changes ''' curFile = Path( file( q=True, sn=True ) ) referencedMeshes = getRefFilepathDictForNodes( meshes ) if not curFile.name(): printWarningStr( "The current scene isn't saved - please save the current scene first before proceeding!" ) return for refFilepath, refNodeMeshDict in referencedMeshes.iteritems(): referencesToUnload = [] #make sure we don't visit any of the meshes more than once meshesToUpdateWeightsOn = [] meshesToUpdateWeightsOn_withNS = [] for refNode, refMeshes in refNodeMeshDict.iteritems(): #get the maya filepath for the reference (with the "copy number") mayaFilepathForRef = referenceQuery( refNode, f=True ) #get the namespace for this reference refNodeNamespace = file( mayaFilepathForRef, q=True, namespace=True ) #check to see if there are any meshes in this reference that we need to store weights for for mesh_withNS in refMeshes: mesh = stripNamespaceFromNamePath( mesh_withNS, refNodeNamespace ) if mesh in meshesToUpdateWeightsOn: continue meshesToUpdateWeightsOn.append( mesh ) meshesToUpdateWeightsOn_withNS.append( (mesh_withNS, refNodeNamespace) ) #append the file to the list of reference files that we need to unload referencesToUnload.append( mayaFilepathForRef ) #get a list of skin cluster nodes - its actually the skin cluster nodes we want to remove edits from... nodesToCleanRefEditsFrom = [] for m, ns in meshesToUpdateWeightsOn_withNS: nodesToCleanRefEditsFrom.append( mel.findRelatedSkinCluster( m ) ) #now we want to store out the weighting from the referenced meshes weights = [] for mesh, meshNamespace in meshesToUpdateWeightsOn_withNS: weights.append( storeWeightsById( mesh, meshNamespace ) ) #also lets remove any ref edits from the mesh and all of its shape nodes - this isn't strictly nessecary, but I can't think of a reason to make edits to these nodes outside of their native file nodesToCleanRefEditsFrom.append( mesh ) nodesToCleanRefEditsFrom += listRelatives( mesh, s=True, pa=True ) or [] #remove the skinweights reference edits from the meshes in the current scene for f in referencesToUnload: file( f, unloadReference=True ) #remove ref edits from the shape node as well - this isn't strictly nessecary but there probably shouldn't be changes to the shape node anyway for node in nodesToCleanRefEditsFrom: referenceEdit( node, removeEdits=True, successfulEdits=True, failedEdits=True ) #re-load references for f in referencesToUnload: file( f, loadReference=True ) #save this scene now that we've removed ref edits ensureCurrentFileIsCheckedOut() file( save=True, f=True ) #load up the referenced file and apply the weighting to the meshes in that scene file( refFilepath, open=True, f=True ) for mesh, weightData in zip( meshesToUpdateWeightsOn, weights ): #if there is no weight data to store - keep loopin... if not weightData: continue skinCluster = mel.findRelatedSkinCluster( mesh ) if not skinCluster: printWarningStr( "Couldn't find a skin cluster driving %s - skipping this mesh" % mesh ) continue skinWeights.setSkinWeights( skinCluster, weightData ) #save the referenced scene now that we've applied the weights to it ensureCurrentFileIsCheckedOut() file( save=True, f=True ) #reload the original file file( curFile, o=True, f=True )
import os from consoleChroma import Good from filesystem import Path, removeDupes from dependencies import generateDepTree, makeScriptPathRelative _THIS_FILE = Path( os.path.abspath( __file__ ) ) _PYTHON_TOOLS_TO_PACKAGE = _THIS_FILE.up() / 'pythonToolsToPackage.txt' _PACKAGE_DIR_NAME = 'zooToolboxPy' _PACKAGE_DIR = _THIS_FILE.up( 2 ) / _PACKAGE_DIR_NAME def cleanPackageDir(): if _PACKAGE_DIR.exists: _PACKAGE_DIR.delete() _PACKAGE_DIR.create() def buildPackage( dependencyTree=None ): if not _PYTHON_TOOLS_TO_PACKAGE.exists: raise ValueError( "Cannot find %s file!" % _PYTHON_TOOLS_TO_PACKAGE.name() ) modulesToPackage = [] for toolName in _PYTHON_TOOLS_TO_PACKAGE.read(): if toolName: if toolName.startswith( '#' ): continue elif toolName.startswith( '//' ): continue
def getFile( cls ): clsFile = Path( inspect.getfile( cls ) ) if clsFile.setExtension( 'py' ).exists(): return clsFile.setExtension( 'py' ) return clsFile
def ensureCurrentFileIsCheckedOut(): curFile = Path( file( q=True, sn=True ) ) if not curFile.getWritable(): curFile.edit()