def eval(self, expr, env): if not datatypes.isFuthonObj(expr): if isinstance(expr, list): return self.eval_list(expr, env) return expr elif datatypes.isSymbol(expr): return env.get(expr) elif datatypes.isKeyword(expr): return expr elif datatypes.isVector(expr): return datatypes.Vector([self.eval(e, env) for e in expr]) elif datatypes.isSet(expr): return datatypes.Set([self.eval(e, env) for e in expr]) raise Exception("evaluation not yet implemented for type " + str(type(expr)))
def getVector(self): import datatypes x = cmds.floatFieldGrp(self, q=1, v1=True) y = cmds.floatFieldGrp(self, q=1, v2=True) z = cmds.floatFieldGrp(self, q=1, v3=True) return datatypes.Vector([x, y, z])
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 _vector(self, node): return datatypes.Vector(node.tail)
def _vector_set(vector, num, value): assert isinstance(vector, datatypes.Vector) vector.set(num, value) def _vector_fill(vector, fill_value): assert isinstance(vector, datatypes.Vector) vector.fill(fill_value) functions = { '+': _add, '-': _sub, '*': _mul, '/': _div, 'list': _list, 'cons': _cons, 'car': _car, 'cdr': _cdr, '>': _gt, '<': _lt, '>=': _ge, '<=': _le, 'print!': _print, 'vector': lambda *contents: datatypes.Vector(contents), 'make-vector': lambda *args: datatypes.Vector.make(*args), 'vector?': _is_vector, 'vector-length': _vector_length, 'vector-ref': _vector_ref, 'vector-set!': _vector_set, 'vector-fill!': _vector_fill, }
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()
def test_vector(self): parser = futhon_parser.FuthonParser() env = environment.GlobalEnvironment({}) ev = evaluator.Evaluator() self.assertEqual(datatypes.Vector([5, 4, 3]), ev.eval(parser.parse("[5, 4, 3]"), env))