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
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()) ]
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()