Пример #1
0
 def getSkinWeights(self, skin, indices=None, influences=None):
     '''
     Get a list of all vertices and associated weights
     Returns:
         [(vert,weights)]
     '''
     data = []
     _influences = self.getSkinInfluences(skin)
     influences = _influences
     # getAttr is faster
     weightListPlug = skin.wl.__apiobject__()
     infIDs = api.MIntArray()
     weightListPlug.getExistingArrayAttributeIndices(infIDs)
     for vert in infIDs:
         if indices is not None and vert not in indices:
             continue
         weights = []
         weightsPlug = skin.wl[vert].weights.__apiobject__()
         # loop through all weights
         for i in xrange(weightsPlug.numElements()):
             # get the logical index, which will match the indices of influences list
             logical = weightsPlug[i].logicalIndex()
             if logical in influences:
                 weights.append((influences[logical], weightsPlug[i].asFloat()))
         data.append((vert, weights))
     return data
Пример #2
0
    def eval(cls, cmd):
        """
        evaluate a string as a mel command and return the result.

        Behaves like maya.mel.eval, with several improvements:
            - returns pymel `Vector` and `Matrix` classes
            - when an error is encountered a `MelError` exception is raised, along with the line number (if enabled) and exact mel error.

        >>> mel.eval( 'attributeExists("persp", "translate")' )
        0
        >>> mel.eval( 'interToUI( "fooBarSpangle" )' )
        u'Foo Bar Spangle'

        """
        # should return a value, like _mm.eval
        #return _mm.eval( cmd )
        # get this before installing the callback
        undoState = _mc.undoInfo(q=1, state=1)
        lineNumbers = _mc.commandEcho(q=1, lineNumbers=1)
        _mc.commandEcho(lineNumbers=1)
        global errors
        errors = []  # a list to store each error line

        def errorCallback(nativeMsg, messageType, data):
            global errors
            if messageType == _api.MCommandMessage.kError:
                if nativeMsg:
                    errors += [nativeMsg]

        # setup the callback:
        # assigning ids to a list avoids the swig memory leak warning, which would scare a lot of people even though
        # it is harmless.  hoping we get a real solution to this so that we don't have to needlessly accumulate this data
        id = _api.MCommandMessage.addCommandOutputCallback(errorCallback, None)

        try:
            res = _api.MCommandResult()
            _api.MGlobal.executeCommand(cmd, res, False, undoState)
        except Exception:
            # these two lines would go in a finally block, but we have to maintain python 2.4 compatibility for maya 8.5
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()

            msg = '\n'.join(errors)

            if 'Cannot find procedure' in msg:
                e = MelUnknownProcedureError
            elif 'Wrong number of arguments' in msg:
                e = MelArgumentError
                if cls.proc:
                    # remove the calling proc, it will be added below
                    msg = msg.split('\n', 1)[1].lstrip()
            elif 'Cannot convert data' in msg or 'Cannot cast data' in msg:
                e = MelConversionError
            elif 'Syntax error' in msg:
                e = MelSyntaxError
            else:
                e = MelError
            message = "Error during execution of MEL script: %s" % (msg)
            fmtCmd = '\n'.join(['  ' + x for x in cmd.split('\n')])

            if cls.proc:
                if e is not MelUnknownProcedureError:
                    file = _mm.eval('whatIs "%s"' % cls.proc)
                    if file.startswith('Mel procedure found in: '):
                        file = 'file "%s"' % os.path.realpath(
                            file.split(':')[1].lstrip())
                    message += '\nCalling Procedure: %s, in %s' % (cls.proc,
                                                                   file)
                    message += '\n' + fmtCmd
            else:
                message += '\nScript:\n%s' % fmtCmd
            raise e, message
        else:
            # these two lines would go in a finally block, but we have to maintain python 2.4 compatibility for maya 8.5
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()
            resType = res.resultType()

            if resType == _api.MCommandResult.kInvalid:
                return
            elif resType == _api.MCommandResult.kInt:
                result = _api.SafeApiPtr('int')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kIntArray:
                result = _api.MIntArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kDouble:
                result = _api.SafeApiPtr('double')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kDoubleArray:
                result = _api.MDoubleArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kString:
                return res.stringResult()
            elif resType == _api.MCommandResult.kStringArray:
                result = []
                res.getResult(result)
                return result
            elif resType == _api.MCommandResult.kVector:
                result = _api.MVector()
                res.getResult(result)
                return datatypes.Vector(result)
            elif resType == _api.MCommandResult.kVectorArray:
                result = _api.MVectorArray()
                res.getResult(result)
                return [
                    datatypes.Vector(result[i]) for i in range(result.length())
                ]
            elif resType == _api.MCommandResult.kMatrix:
                result = _api.MMatrix()
                res.getResult(result)
                return datatypes.Matrix(result)
            elif resType == _api.MCommandResult.kMatrixArray:
                result = _api.MMatrixArray()
                res.getResult(result)
                return [
                    datatypes.Matrix(result[i]) for i in range(result.length())
                ]
Пример #3
0
    def _eval(cls, cmd, commandName):
        # commandName is just used for nicer formatting of error messages,
        # and is used by MelCallable

        # should return a value, like _mm.eval
        # return _mm.eval( cmd )
        # get this before installing the callback
        undoState = _mc.undoInfo(q=1, state=1)
        lineNumbers = _mc.commandEcho(q=1, lineNumbers=1)
        _mc.commandEcho(lineNumbers=1)
        global errors
        errors = []  # a list to store each error line

        def errorCallback(nativeMsg, messageType, data):
            global errors
            if messageType == _api.MCommandMessage.kError:
                if nativeMsg:
                    errors += [nativeMsg]

        # setup the callback:
        # assigning ids to a list avoids the swig memory leak warning, which would scare a lot of people even though
        # it is harmless.  hoping we get a real solution to this so that we don't have to needlessly accumulate this data
        id = _api.MCommandMessage.addCommandOutputCallback(errorCallback, None)

        try:
            res = _api.MCommandResult()
            _api.MGlobal.executeCommand(cmd, res, False, undoState)
        except Exception:
            msg = '\n'.join(errors)

            if 'Cannot find procedure' in msg:
                e = MelUnknownProcedureError
            elif 'Wrong number of arguments' in msg:
                e = MelArgumentError
                if commandName:
                    # remove the calling proc, it will be added below
                    msg = msg.split('\n', 1)[1].lstrip()
            elif 'Cannot convert data' in msg or 'Cannot cast data' in msg:
                e = MelConversionError
            elif 'Syntax error' in msg:
                e = MelSyntaxError
            else:
                e = MelError
            message = "Error during execution of MEL script: %s" % (msg)
            fmtCmd = '\n'.join(['  ' + x for x in cmd.split('\n')])

            if commandName:
                if e is not MelUnknownProcedureError:
                    file = _mm.eval('whatIs "%s"' % commandName)
                    if file.startswith('Mel procedure found in: '):
                        file = 'file "%s"' % os.path.realpath(file.split(':')[1].lstrip())
                    message += '\nCalling Procedure: %s, in %s' % (commandName, file)
                    message += '\n' + fmtCmd
            else:
                message += '\nScript:\n%s' % fmtCmd
            raise e, message
        else:
            resType = res.resultType()

            if resType == _api.MCommandResult.kInvalid:
                return
            elif resType == _api.MCommandResult.kInt:
                result = _api.SafeApiPtr('int')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kIntArray:
                result = _api.MIntArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kDouble:
                result = _api.SafeApiPtr('double')
                res.getResult(result())
                return result.get()
            elif resType == _api.MCommandResult.kDoubleArray:
                result = _api.MDoubleArray()
                res.getResult(result)
                return [result[i] for i in range(result.length())]
            elif resType == _api.MCommandResult.kString:
                return res.stringResult()
            elif resType == _api.MCommandResult.kStringArray:
                result = []
                res.getResult(result)
                return result
            elif resType == _api.MCommandResult.kVector:
                result = _api.MVector()
                res.getResult(result)
                return datatypes.Vector(result)
            elif resType == _api.MCommandResult.kVectorArray:
                result = _api.MVectorArray()
                res.getResult(result)
                return [datatypes.Vector(result[i]) for i in range(result.length())]
            elif resType == _api.MCommandResult.kMatrix:
                result = _api.MMatrix()
                res.getResult(result)
                return datatypes.Matrix(result)
            elif resType == _api.MCommandResult.kMatrixArray:
                result = _api.MMatrixArray()
                res.getResult(result)
                return [datatypes.Matrix(result[i]) for i in range(result.length())]
        finally:
            _api.MMessage.removeCallback(id)
            _mc.commandEcho(lineNumbers=lineNumbers)
            # 8.5 fix
            if hasattr(id, 'disown'):
                id.disown()