def testFunctionalString(self): for is_array in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode(mc.spaceLocator(name="in_node")[0]) out_node = MNode(mc.spaceLocator(name="out_node")[0]) attr_type = "string" input_attr = "string_test" input_value = "test_string_value" output_attr = "string_test" output_attr_2 = "string_test2" anim_values = None self._runFunctionalTest(in_node, out_node, attr_type, input_attr, output_attr, input_attr, anim_values, is_array, input_value=input_value, output_attr_2=output_attr_2)
def testFunctionalAngle(self): for is_array in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode(mc.spaceLocator(name="in_node")[0]) out_node = MNode(mc.spaceLocator(name="out_node")[0]) attr_type = "angle" input_attr = "rotateX" output_attr = "rotateX" out_attr_2 = "rotateY" anim_values = (1.0, 100.0) self._runFunctionalTest(in_node, out_node, attr_type, input_attr, output_attr, input_attr, anim_values, is_array, output_attr_2=out_attr_2)
def testFunctionalEuler(self): for is_array in (False, True): for use_comp_names in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode(mc.spaceLocator(name="in_node")[0]) out_node = MNode(mc.spaceLocator(name="out_node")[0]) attr_type = MPyNode.ATTR_TYPE_EULER input_attr = "rotate" output_attr = "rotate" output_attr_2 = "scale" anim_values = ((1.0, 1.0, 1.0), (100.0, 200.0, 300.0)) self._runFunctionalTest(in_node, out_node, attr_type, input_attr, output_attr, input_attr, anim_values, is_array, output_attr_2=output_attr_2, use_comp_names=use_comp_names)
def testFunctionalBool(self): for is_array in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode(mc.spaceLocator(name="in_node")[0]) out_node = MNode(mc.spaceLocator(name="out_node")[0]) attr_type = "bool" input_attr = "testBool" output_attr = "testBool" out_attr_2 = "testBool2" anim_values = (True, False) self._runFunctionalTest(in_node, out_node, attr_type, input_attr, output_attr, input_attr, anim_values, is_array, output_attr_2=out_attr_2)
def testFunctionalMatrix(self): for is_array in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode(mc.spaceLocator(name="in_node")[0]) out_node = MNode.createNode("multMatrix", name="matrix_out_node") attr_type = "matrix" input_attr = "matrix" output_attr = "matrixIn[0]" output_attr_2 = "matrixIn[1]" anim_attr = "translate" anim_values = ((1.0, 1.0, 1.0), (100.0, 200.0, 300.0)) self._runFunctionalTest(in_node, out_node, attr_type, input_attr, output_attr, anim_attr, anim_values, is_array, output_attr_2=output_attr_2)
def testFunctionalEnum(self): for is_array in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode(mc.spaceLocator(name="in_node")[0]) out_node = MNode(mc.spaceLocator(name="out_node")[0]) attr_type = "enum" input_attr = "testEnum" output_attr = "testEnum" output_attr_2 = "testEnum2" enum_names = ":".join(["enum" + str(i) for i in xrange(100)]) attr_kargs = {"enumName": enum_names} anim_values = (1, 100) self._runFunctionalTest(in_node, out_node, attr_type, input_attr, output_attr, input_attr, anim_values, is_array, output_attr_2=output_attr_2, attr_kargs=attr_kargs)
def testChildClass(self): mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode(mc.spaceLocator(name="in_node")[0]) out_node = MNode(mc.spaceLocator(name="out_node")[0]) py_node = TestChildClass() for i, attr_name in enumerate(TestChildClass.INIT_INPUT_ATTRS): self.assertTrue(py_node.hasAttr(attr_name)) for i, attr_name in enumerate(TestChildClass.INIT_OUTPUT_ATTRS): self.assertTrue(py_node.hasAttr(attr_name)) for i, attr_name in enumerate(TestChildClass.INIT_ATTRS): self.assertTrue(py_node.hasAttr(attr_name)) attr_type = "float" input_attr = "translateX" output_attr = "translateX" anim_values = (1.0, 100.0) self._runFunctionalTest(in_node, out_node, attr_type, input_attr, output_attr, input_attr, anim_values, False, py_node=py_node)
def testFunctionalMesh(self): for is_array in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) num_meshes = 1 if not is_array else 4 in_nodes = [] geo_points = [] for i in range(num_meshes): cube_trans = mc.polyCube(name="in_node_" + str(i), ch=False)[0] new_mesh = MNode( mc.listRelatives(cube_trans, shapes=True, fullPath=True)[0]) in_nodes.append(new_mesh) fn_set = om.MFnMesh(new_mesh) geo_points.append(fn_set.getPoints(om.MSpace.kObject)) attr_type = "mesh" input_attr = "worldMesh[0]" expr_str = "outAttr = inGeo.getPoints()" if not is_array else "outAttr = inGeo[0].getPoints()" anim_values = None self._runFunctionalGeoTest(in_nodes, input_attr, attr_type, is_array, expr_str, geo_points)
def testFunctionalTime(self): for is_array in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode("time1") out_node = MNode.createNode("animBlendNodeTime", name="out_node") attr_type = "time" input_attr = "outTime" output_attr = "inputA" output_attr_2 = "inputB" anim_values = None self._runFunctionalTest(in_node, out_node, attr_type, input_attr, output_attr, input_attr, anim_values, is_array)
def testFunctionalStoredVariables(self): in_node = MNode.createNode("transform", name="in_node") out_node = MNode.createNode("transform", name="out_node") node = self.TEST_CLASS(name="test_py_node") node.addStoredVariable("testVar") node.addInputAttr("inAttr", "float", keyable=True, defaultValue=-1.0) node.addOutputAttr("outAttr", "float") node.setExpression( "if not hasattr(self, 'testVar'):\n\tself.testVar = 1.0\nelse:\n\tself.testVar += 1.0\noutAttr = self.testVar\n" ) in_node.connectAttr("translateX", node, "inAttr") node.connectAttr("outAttr", out_node, "translateX") in_node.setAttr("translateX", 1.0) out_value = out_node.getAttr("translateX") self.assertEqual(out_value, 1.0) out_file_name = os.environ["TEMP"].replace("\\", "/") + "/test_mpynode.ma" mc.file(rename=out_file_name) mc.file(save=True, force=True, type="mayaAscii") for i in range(2, 100): mc.file(out_file_name, open=True, force=True) in_node = MNode("in_node") out_node = MNode("out_node") in_node.setAttr("translateX", float(i) + 1.0) out_value = out_node.getAttr("translateX") self.assertEqual(out_value, float(i)) mc.file(save=True, force=True, type="mayaAscii")
def _runFunctionalGeoTest(self, in_nodes, input_attr, attr_type, is_array, expr_str, geo_points, attr_kargs=None): if attr_kargs is None: attr_kargs = {} out_node = MNode(mc.spaceLocator(name="out_node")[0]) py_node = self.TEST_CLASS(name="test_py_node") py_node.setExpression(expr_str) py_node.addInputAttr("inGeo", attr_type, is_array=is_array, **attr_kargs) py_node.addOutputAttr("outAttr", "vector", is_array=True, **attr_kargs) py_node.addInputAttr("inTime", "time") py_node.addOutputAttr("computeCount", "int") if not is_array: in_nodes[0].connectAttr(input_attr, py_node, "inGeo") else: for i, in_node in enumerate(in_nodes): in_node.connectAttr(input_attr, py_node, "inGeo[" + str(i) + "]") for i in range(len(in_nodes)): print py_node.getAttr("outAttr[" + str(i) + "]")
def testFunctionalPy(self): for is_array in (False, True): mc.file(newFile=True, force=True) mc.playbackOptions(e=True, minTime=1, maxTime=100) in_node = MNode(mc.spaceLocator(name="in_node")[0]) out_node = MNode(mc.spaceLocator(name="out_node")[0]) in_py_node = MPyNode(name="in_py_node") out_py_node = MPyNode(name="out_py_node") in_py_node.addInputAttr("inFloat", MPyNode.ATTR_TYPE_FLOAT) in_py_node.addOutputAttr("outPy", MPyNode.ATTR_TYPE_PY, is_array=is_array) out_py_node.addInputAttr("inPy", MPyNode.ATTR_TYPE_PY, is_array=is_array) out_py_node.addOutputAttr("outFloat", MPyNode.ATTR_TYPE_FLOAT) if not is_array: in_py_node.setExpression("outPy = {'test':inFloat}") out_py_node.setExpression( "outFloat = inPy['test'] + inPy['test']") in_node.connectAttr("tx", in_py_node, "inFloat") in_py_node.connectAttr("outPy", out_py_node, "inPy") out_py_node.connectAttr("outFloat", out_node, "tx") else: in_py_node.setExpression( "outPy = [{'test':inFloat}, {'test':inFloat}]") out_py_node.setExpression( "outFloat = inPy[0]['test'] + inPy[1]['test']") in_node.connectAttr("tx", in_py_node, "inFloat") in_py_node.connectAttr("outPy[0]", out_py_node, "inPy[0]") in_py_node.connectAttr("outPy[1]", out_py_node, "inPy[1]") out_py_node.connectAttr("outFloat", out_node, "tx") for f in xrange(101): mc.currentTime(f, update=True) in_node.setAttr("tx", float(f)) out_val = out_node.getAttr("tx") self.assertEqual(float(f) + float(f), out_val)
def _runFunctionalTest(self, in_node, out_node, attr_type, input_attr, output_attr, anim_attr, anim_values, is_array, py_node=None, out_attr_type=None, input_value=None, expr_str=None, output_attr_2=None, attr_kargs=None, use_comp_names=False): in_node_name = str(in_node) out_node_name = str(out_node) in_attr_name = "inAttr" out_attr_name = "outAttr" comp_count_attr = "computeCount" attr_mel_type = MPyNode._NEW_INPUT_TYPES[attr_type] out_mel_type = MPyNode._NEW_OUTPUT_TYPES[ attr_type] if not out_attr_type else MPyNode._NEW_OUTPUT_TYPES[ out_attr_type] if attr_kargs is None: attr_kargs = {} if expr_str is None: expr_str = "outAttr = inAttr\nif not hasattr(self, '_comp_count'):\n self._comp_count = 0\nelse: self._comp_count += 1\ncomputeCount=self._comp_count" if not out_attr_type: out_attr_type = attr_type if not py_node: py_node = self.TEST_CLASS(name="test_py_node") py_node.setExpression(expr_str) py_node.addInputAttr(in_attr_name, attr_type, is_array=is_array, **attr_kargs) py_node.addOutputAttr(out_attr_name, out_attr_type, is_array=is_array, **attr_kargs) py_node.addInputAttr( "dummyInput", "float", is_array=True ) ##adding to make sure it doesn't cause multiple calls to compute() py_node.setAttr("dummyInput", size=10) py_node.addOutputAttr(comp_count_attr, "int") if not in_node.hasAttr(input_attr): in_node.addAttr(input_attr, attr_mel_type, keyable=True, **attr_kargs) if not out_node.hasAttr(output_attr.split("[")[0]): out_node.addAttr(output_attr, out_mel_type, keyable=True, **attr_kargs) pynode_in_attr = in_attr_name if not is_array else in_attr_name + "[0]" pynode_out_attr = out_attr_name if not is_array else out_attr_name + "[0]" py_node.connectAttr(pynode_out_attr, out_node, output_attr) if not use_comp_names: in_node.connectAttr(input_attr, py_node, pynode_in_attr) else: for i, axis in enumerate(("X", "Y", "Z")): comp_name = MPyNode._VECTOR_COMP_NAMES[attr_type][i] if is_array: in_node.connectAttr( input_attr + axis, py_node, pynode_in_attr + "." + in_attr_name + comp_name) else: in_node.connectAttr(input_attr + axis, py_node, in_attr_name + comp_name) if is_array and output_attr_2: py_node.setAttr(out_attr_name, size=2) if not out_node.hasAttr(output_attr_2.split("[")[0]): out_node.addAttr(output_attr_2, attr_mel_type, **attr_kargs) py_node.connectAttr(out_attr_name + "[1]", out_node, output_attr_2) child_in_attrs = in_node.attributeQuery(anim_attr, listChildren=True) if input_value is not None: in_node.setAttr(anim_attr, input_value, type=attr_mel_type) if anim_values is not None: ##---not a compound attr---## if not child_in_attrs: mc.setKeyframe(in_node, attribute=anim_attr, time=1, value=anim_values[0]) mc.setKeyframe(in_node, attribute=anim_attr, time=100, value=anim_values[1]) ##---compound attr---## else: for i, child_attr in enumerate(child_in_attrs): mc.setKeyframe(in_node, attribute=anim_attr, time=1, value=anim_values[0][i]) mc.setKeyframe(in_node, attribute=anim_attr, time=100, value=anim_values[1][i]) out_file_name = os.environ["TEMP"].replace("\\", "/") + "/test_mpynode.ma" py_node_name = str(py_node) mc.file(rename=out_file_name) mc.file(save=True, force=True, type="mayaAscii") for i in xrange(2): ##--reopen scene second time around---## if i: mc.file(out_file_name, open=True, force=True) in_node = MNode(in_node_name) out_node = MNode(out_node_name) py_node = self.TEST_CLASS(py_node_name) if not anim_values and attr_mel_type != "time": in_node.setAttr(input_attr, input_value, type=attr_mel_type) for f in xrange(101): mc.currentTime(f, update=True) in_val = in_node.getAttr(input_attr) out_val = out_node.getAttr(output_attr) self.assertEqual(in_val, out_val) if attr_type != "string": self.assertTrue(py_node.getAttr("computeCount") in (99, 100)) if os.path.exists(out_file_name): os.remove(out_file_name)