예제 #1
0
파일: apicache.py 프로젝트: cgrebeld/pymel
    def build(self, rebuildAllButClassInfo=False):
        """
        Used to rebuild api cache, either by loading from a cache file, or rebuilding from scratch.

        Set 'rebuildAllButClassInfo' to True to force rebuilding of all info BUT self.apiClassInfo -
        this is useful for versions < 2009, as these versions cannot parse the api docs; by setting
        this to False, you can rebuild all other api information.
        """

        # Need to initialize this to possibly pass into _buildself.apiTypeHierarchy, if rebuildAllButClassInfo
        self.apiClassInfo = None

        data = startup.loadCache( 'mayaApi', 'the API cache', compressed=True )

        self._buildMayaReservedTypes()

        if data is not None:

            #self.reservedMayaTypes = data[0]
            #self.reservedApiTypes = data[1]
            self.apiTypesToApiEnums = data[2]
            self.apiEnumsToApiTypes = data[3]
            self.mayaTypesToApiTypes = data[4]
            self.apiTypesToApiClasses = data[5]
            self.apiTypeHierarchy = data[6]
            self.apiClassInfo = data[7]


            if not rebuildAllButClassInfo:
                # Note that even if rebuildAllButClassInfo, we still want to load
                # the cache file, in order to grab self.apiClassInfo
                return


        _logger.info( "Rebuilding the API Caches..." )

        # fill out the data structures
        self._buildApiTypesList()
        #self.apiTypesToApiEnums, self.apiTypesToApiClasses = self._buildApiTypesList()
        #_buildMayaTypesList()

        if not rebuildAllButClassInfo:
            self.apiClassInfo = None

        self._buildApiTypeHierarchy()

        # merge in the manual overrides: we only do this when we're rebuilding or in the pymelControlPanel
        _logger.info( 'merging in dictionary of manual api overrides')
        _util.mergeCascadingDicts( apiClassOverrides, self.apiClassInfo, allowDictToListMerging=True )

        startup.writeCache( ( self.reservedMayaTypes, self.reservedApiTypes,
                               self.apiTypesToApiEnums, self.apiEnumsToApiTypes,
                               self.mayaTypesToApiTypes,
                               self.apiTypesToApiClasses, self.apiTypeHierarchy, self.apiClassInfo ),
                               'mayaApi', 'the API cache' )

        return
예제 #2
0
파일: apicache.py 프로젝트: cgrebeld/pymel
def loadApiToMelBridge():

    data = startup.loadCache( 'mayaApiMelBridge', 'the API-MEL bridge', useVersion=False, compressed=True )
    if data is not None:
        # maya 8.5 fix: convert dict to defaultdict
        bridge, overrides = data
        bridge = _util.defaultdict(dict, bridge)
        return bridge, overrides

    # no bridge cache exists. create default
    bridge = _util.defaultdict(dict)

    # no api overrides exist. create default
    overrides = {}

    return bridge, overrides
예제 #3
0
def buildCachedData() :
    """Build and save to disk the list of Maya Python commands and their arguments"""

    # With extension can't get docs on unix 64
    # path is
    # /usr/autodesk/maya2008-x64/docs/Maya2008/en_US/Nodes/index_hierarchy.html
    # and not
    # /usr/autodesk/maya2008-x64/docs/Maya2008-x64/en_US/Nodes/index_hierarchy.html
    long_version = versions.installName()

    data = startup.loadCache( 'mayaCmdsList', 'the list of Maya commands' )

    if data is not None:
        cmdlist,nodeHierarchy,uiClassList,nodeCommandList,moduleCmds = data

    else: # or not isinstance(cmdlist,list):
        cmdlist = {}
        _logger.info("Rebuilding the list of Maya commands...")

        nodeHierarchy = _getNodeHierarchy(long_version)
        nodeFunctions = [ x[0] for x in nodeHierarchy ]
        nodeFunctions += nodeTypeToNodeCommand.values()

        #nodeHierarchyTree = trees.IndexedTree(nodeHierarchy)
        uiClassList = UI_COMMANDS
        nodeCommandList = []
        for moduleName, longname in moduleNameShortToLong.items():
            moduleNameShortToLong[moduleName] = getModuleCommandList( longname, long_version )

        tmpCmdlist = inspect.getmembers(cmds, callable)
        cmdlist = {}
        #moduleCmds = defaultdict(list)
        moduleCmds = dict( (k,[]) for k in moduleNameShortToLong.keys() )
        moduleCmds.update( {'other':[], 'runtime': [], 'context': [], 'uiClass': [] } )

        for funcName, data in tmpCmdlist :
            # determine to which module this function belongs
            module = None
            if funcName in ['eval', 'file', 'filter', 'help', 'quit']:
                module = None
            elif funcName.startswith('ctx') or funcName.endswith('Ctx') or funcName.endswith('Context'):
                module = 'context'
            #elif funcName in uiClassList:
            #    module = 'uiClass'
            #elif funcName in nodeHierarchyTree or funcName in nodeTypeToNodeCommand.values():
            #    module = 'node'
            else:
                for moduleName, commands in moduleNameShortToLong.iteritems():
                    if funcName in commands:
                        module = moduleName
                        break
                if module is None:
                    if mm.eval('whatIs "%s"' % funcName ) == 'Run Time Command':
                        module = 'runtime'
                    else:
                        module = 'other'

            cmdInfo = {}

            if module:
                moduleCmds[module].append(funcName)

            if module != 'runtime':
                cmdInfo = getCmdInfo(funcName, long_version)

                if module != 'windows':
                    if funcName in nodeFunctions:
                        nodeCommandList.append(funcName)
                        cmdInfo = testNodeCmd( funcName, cmdInfo, nodeCmd=True, verbose=True  )
                    #elif module != 'context':
                    #    cmdInfo = testNodeCmd( funcName, cmdInfo, nodeCmd=False, verbose=True  )

            cmdInfo['type'] = module
            flags = getCallbackFlags(cmdInfo)
            if flags:
                cmdInfo['callbackFlags'] = flags

            cmdlist[funcName] = cmdInfo


#            # func, args, (usePyNode, baseClsName, nodeName)
#            # args = dictionary of command flags and their data
#            # usePyNode = determines whether the class returns its 'nodeName' or uses PyNode to dynamically return
#            # baseClsName = for commands which should generate a class, this is the name of the superclass to inherit
#            # nodeName = most creation commands return a node of the same name, this option is provided for the exceptions
#            try:
#                cmdlist[funcName] = args, pymelCmdsList[funcName] )
#            except KeyError:
#                # context commands generate a class based on unicode (which is triggered by passing 'None' to baseClsName)
#                if funcName.startswith('ctx') or funcName.endswith('Ctx') or funcName.endswith('Context'):
#                     cmdlist[funcName] = (funcName, args, (False, None, None) )
#                else:
#                    cmdlist[funcName] = (funcName, args, () )

        # split the cached data for lazy loading
        cmdDocList = {}
        examples = {}
        for cmdName, cmdInfo in cmdlist.iteritems():
            try:
                examples[cmdName] = cmdInfo.pop('example')
            except KeyError:
                pass

            newCmdInfo = {}
            if 'description' in cmdInfo:
                newCmdInfo['description'] = cmdInfo.pop('description')
            newFlagInfo = {}
            if 'flags' in cmdInfo:
                for flag, flagInfo in cmdInfo['flags'].iteritems():
                    newFlagInfo[flag] = { 'docstring' : flagInfo.pop('docstring') }
                newCmdInfo['flags'] = newFlagInfo

            if newCmdInfo:
                cmdDocList[cmdName] = newCmdInfo

        startup.writeCache( (cmdlist,nodeHierarchy,uiClassList,nodeCommandList,moduleCmds),
                              'mayaCmdsList', 'the list of Maya commands',compressed=True )

        startup.writeCache( cmdDocList,
                              'mayaCmdsDocs', 'the Maya command documentation',compressed=True )

        startup.writeCache( examples,
                              'mayaCmdsExamples', 'the list of Maya command examples',compressed=True )

    # corrections that are always made, to both loaded and freshly built caches

    util.mergeCascadingDicts( cmdlistOverrides, cmdlist )
    # add in any nodeCommands added after cache rebuild
    nodeCommandList = set(nodeCommandList).union(nodeTypeToNodeCommand.values())
    nodeCommandList = sorted( nodeCommandList )


    for module, funcNames in moduleCommandAdditions.iteritems():
        for funcName in funcNames:
            currModule = cmdlist[funcName]['type']
            if currModule != module:
                cmdlist[funcName]['type'] = module
                id = moduleCmds[currModule].index(funcName)
                moduleCmds[currModule].pop(id)
                moduleCmds[module].append(funcName)
    return (cmdlist,nodeHierarchy,uiClassList,nodeCommandList,moduleCmds)
예제 #4
0
def fixCodeExamples(style='maya', force=False):
    """cycle through all examples from the maya docs, replacing maya.cmds with pymel and inserting pymel output.

    NOTE: this can only be run from gui mode
    WARNING: back up your preferences before running

    TODO: auto backup and restore of maya prefs
    """

    manipOptions = cmds.manipOptions( q=1, handleSize=1, scale=1 )
    animOptions = []
    animOptions.append( cmds.animDisplay( q=1, timeCode=True ) )
    animOptions.append( cmds.animDisplay( q=1, timeCodeOffset=True )  )
    animOptions.append( cmds.animDisplay( q=1, modelUpdate=True ) )

    openWindows = cmds.lsUI(windows=True)
    examples = startup.loadCache('mayaCmdsExamples', useVersion=True)
    processedExamples = startup.loadCache('mayaCmdsExamples', useVersion=False)
    processedExamples = {} if processedExamples is None else processedExamples
    allCmds = set(examples.keys())
    # put commands that require manual interaction first
    manualCmds = ['fileBrowserDialog', 'fileDialog', 'fileDialog2', 'fontDialog']
    skipCmds = ['colorEditor', 'emit', 'finder', 'doBlur', 'messageLine', 'renderWindowEditor', 'ogsRender', 'webBrowser']
    allCmds.difference_update(manualCmds)
    allCmds.difference_update(skipCmds)
    sortedCmds = manualCmds + sorted(allCmds)
    for command in sortedCmds:
        example = examples[command]

        if not force and command in processedExamples:
            _logger.info("%s: already completed. skipping." % command)
            continue

        _logger.info("Starting command %s", command)

        # change from cmds to pymel
        reg = re.compile(r'\bcmds\.')
        example = reg.sub( 'pm.', example )
        #example = example.replace( 'import maya.cmds as cmds', 'import pymel as pm\npm.newFile(f=1) #fresh scene' )

        lines = example.split('\n')
        if len(lines)==1:
            _logger.info("removing empty example for command %s", command)
            examples.pop(command)
            continue

        if style == 'doctest' :
            DOC_TEST_SKIP = ' #doctest: +SKIP'
        else:
            DOC_TEST_SKIP = ''

        lines[0] = 'import pymel.core as pm' + DOC_TEST_SKIP
        #lines.insert(1, 'pm.newFile(f=1) #fresh scene')
        # create a fresh scene. this does not need to be in the docstring unless we plan on using it in doctests, which is probably unrealistic
        cmds.file(new=1,f=1)

        newlines = []
        statement = []

        # narrowed down the commands that cause maya to crash to these prefixes
        if re.match( '(dis)|(dyn)|(poly)', command) :
            evaluate = False
        elif command in skipCmds:
            evaluate = False
        else:
            evaluate = True

        # gives a little leniency for where spaces are placed in the result line
        resultReg = re.compile('# Result:\s*(.*) #$')
        try: # funky things can happen when executing maya code: some exceptions somehow occur outside the eval/exec
            for i, line in enumerate(lines):
                res = None
                # replace with pymel results  '# Result: 1 #'
                m = resultReg.match(line)
                if m:
                    if evaluate is False:
                        line = m.group(1)
                        newlines.append('    ' + line)
                else:
                    if evaluate:
                        if line.strip().endswith(':') or line.startswith(' ') or line.startswith('\t'):
                            statement.append(line)
                        else:
                            # evaluate the compiled statement using exec, which can do multi-line if statements and so on
                            if statement:
                                try:
                                    #_logger.debug("executing %s", statement)
                                    exec( '\n'.join(statement) )
                                    # reset statement
                                    statement = []
                                except Exception, e:
                                    _logger.info("stopping evaluation %s", str(e))# of %s on line %r" % (command, line)
                                    evaluate = False
                            try:
                                _logger.debug("evaluating: %r" % line)
                                res = eval( line )
                                #if res is not None: _logger.info("result", repr(repr(res)))
                                #else: _logger.info("no result")
                            except:
                                #_logger.debug("failed evaluating:", str(e))
                                try:
                                    exec( line )
                                except (Exception, TypeError), e:
                                    _logger.info("stopping evaluation %s", str(e))# of %s on line %r" % (command, line)
                                    evaluate = False
                    if style == 'doctest':
                        if line.startswith(' ') or line.startswith('\t'):
                            newlines.append('    ... ' + line  )
                        else:
                            newlines.append('    >>> ' + line + DOC_TEST_SKIP )

                        if res is not None:
                            newlines.append( '    ' + repr(res) )
                    else:
                        newlines.append('    ' + line )
                        if res is not None:
                            newlines.append( '    # Result: %r #' % (res,) )

            if evaluate:
                _logger.info("successful evaluation! %s", command)

            example = '\n'.join( newlines )
            processedExamples[command] = example