def test_addremoveAttr(self): trans = nt.createNode("trans", "transform") trans2 = nt.createNode("trans2", "transform") nattr = api.MFnNumericAttribute() attr = nattr.create("longnumattr", "sna", api.MFnNumericData.kLong, 5) trans.addAttribute(attr) attrplug = trans.longnumattr attrplug.msetInt(10) assert attrplug.asInt() == 10 # adding same attribute to several objects - DOES NOT WORK # CREATE A NEW ONE attrnew = nattr.create("longnumattr", "sna", api.MFnNumericData.kLong, 5) trans2.addAttribute(attrnew) trans2.sna.msetInt(20) assert trans2.sna.asInt() == 20 and trans.sna.asInt() == 10 # remove the attribute - with Attribute class this time trans.removeAttribute(attrplug.attribute()) # have to use find plug as our transform has cached the plug which might # have gone out of scope self.failUnlessRaises(RuntimeError, trans.findPlug, "sna")
def test_instancesAndParenting(self): mrvmaya.Scene.open(get_maya_file("instancetest.ma"), force=True) m = nt.Node("m") # mesh, two direct and two indirect instances c1 = nt.createNode("|c1", "transform") assert m.instanceCount(0) == 2 assert m.instanceCount(1) == 4 # test parenting mci = c1.addInstancedChild(m) assert m.instanceCount(0) == 3 assert m.instanceCount(1) == 5 # direct + indirect c1.removeChild(mci) assert m.instanceCount(0) == 2 assert m.instanceCount(1) == 4 # direct + indirect # check reparent d1 = nt.createNode("|d1", "transform") c1 = c1.reparent(d1) assert m.instanceCount(0) == 2 assert m.instanceCount(1) == 4 # reparent an instanced transform under d1 a2 = nt.Node("a2") a2 = a2.reparent(d1, raiseOnInstance=0) # destroys instances assert m.instanceCount(0) == 2 assert m.instanceCount(1) == 2
def test_addremoveAttr( self ): trans = nt.createNode( "trans", "transform" ) trans2 = nt.createNode( "trans2", "transform" ) nattr = api.MFnNumericAttribute( ) attr = nattr.create( "longnumattr", "sna", api.MFnNumericData.kLong, 5 ) trans.addAttribute( attr ) attrplug = trans.longnumattr attrplug.msetInt( 10 ) assert attrplug.asInt() == 10 # adding same attribute to several objects - DOES NOT WORK # CREATE A NEW ONE attrnew = nattr.create( "longnumattr", "sna", api.MFnNumericData.kLong, 5 ) trans2.addAttribute( attrnew ) trans2.sna.msetInt( 20 ) assert trans2.sna.asInt() == 20 and trans.sna.asInt() == 10 # remove the attribute - with Attribute class this time trans.removeAttribute( attrplug.attribute() ) # have to use find plug as our transform has cached the plug which might # have gone out of scope self.failUnlessRaises( RuntimeError, trans.findPlug, "sna" )
def test_instancesAndParenting( self ): mrvmaya.Scene.open( get_maya_file( "instancetest.ma" ), force=True ) m = nt.Node( "m" ) # mesh, two direct and two indirect instances c1 = nt.createNode( "|c1", "transform" ) assert m.instanceCount( 0 ) == 2 assert m.instanceCount( 1 ) == 4 # test parenting mci = c1.addInstancedChild( m ) assert m.instanceCount( 0 ) == 3 assert m.instanceCount( 1 ) == 5 # direct + indirect c1.removeChild( mci ) assert m.instanceCount( 0 ) == 2 assert m.instanceCount( 1 ) == 4 # direct + indirect # check reparent d1 = nt.createNode( "|d1", "transform" ) c1 = c1.reparent( d1 ) assert m.instanceCount( 0 ) == 2 assert m.instanceCount( 1 ) == 4 # reparent an instanced transform under d1 a2 = nt.Node( "a2" ) a2 = a2.reparent( d1, raiseOnInstance=0 ) # destroys instances assert m.instanceCount( 0 ) == 2 assert m.instanceCount( 1 ) == 2
def test_createAddRemove(self): set1 = nt.createNode("set1", "objectSet") set2 = nt.createNode("set2", "objectSet") set3 = nt.createNode("set3", "objectSet") prt1 = nt.createNode("partition1", "partition") prt2 = nt.createNode("partition2", "partition") # SET PARTITION HANDLING ######################### assert len(set1.partitions()) == 0 set1.setPartition(prt1, set1.kReplace) assert len(set1.partitions()) == 1 assert set1.partitions()[0] == prt1 # add same again set1.setPartition(prt1, set1.kAdd) assert len(set1.partitions()) == 1 # remove set1.setPartition(prt1, set1.kRemove) assert len(set1.partitions()) == 0 # remove again set1.setPartition(prt1, set1.kRemove) # PARTITION MEMBER HANDLING # add multiple sets prt1.addSets([set1, set2]) assert len(prt1.members()) == 2 # add again prt1.addSets([set1, set2]) prt1.removeSets([set1, set2]) assert len(prt1.members()) == 0 # remove again prt1.removeSets([set1, set2]) prt2.addSets([set1, set2]) # replace multiple prt2.replaceSets([set3]) # set like methods prt2.add(set1) assert set1 in prt2 prt2.discard(set1) assert set1 not in prt2 # test partition protocols assert len(prt2) == len(prt2.members()) assert [s for s in prt2] == prt2.members() assert set3 in prt2 assert len(prt2) assert isinstance(prt2.clear(), nt.Partition) assert len(prt2) == 0
def test_dagIter( self ): trans = nt.createNode( "trans", "transform" ) trans2 = nt.createNode( "trans2", "transform" ) transinst = trans.addInstancedChild( trans2 ) mesh = nt.createNode( "parent|mesh", "mesh" ) nurbs = nt.createNode( "parent|nurbs", "nurbsSurface" ) assert len( list( iterDagNodes( dagpath=1 ) ) ) == 16 assert len( list( iterDagNodes( dagpath=0 ) ) ) == 15 # BREADTH FIRST ################ dagiter = iterDagNodes( dagpath=1,depth=0,asNode=1 ) for item in dagiter: if item != trans: continue # now the following ones are known ! assert dagiter.next() == trans2 break # DEPTH FIRST ############## dagiter = iterDagNodes( dagpath=1,depth=1,asNode=1 ) for item in dagiter: if item != trans: continue assert dagiter.next() == transinst break # ROOT ######### # MDagpath, DagNode for rootnode in ( trans2, trans2.dagPath() ): dagiter = iterDagNodes( root=rootnode,depth=1,asNode=1 ) nextobj = dagiter.next() assert nextobj == trans2 # END for each root type # MObject only works for instances it appears dagiter = iterDagNodes( root=trans.object(),depth=1,asNode=1 ) assert dagiter.next() == trans assert dagiter.next() == transinst self.failUnlessRaises(StopIteration, dagiter.next) # TYPES # single dagiter = iterDagNodes(api.MFn.kMesh, asNode=1 ) assert len( list( dagiter ) ) == 1 # multiple dagiter = iterDagNodes( api.MFn.kMesh,api.MFn.kNurbsSurface, asNode=1 ) assert len( list( dagiter ) ) == 2
def test_duplicateInstances(self): base = nt.createNode("base", "transform") obase = nt.createNode("obase", "transform") basemesh = nt.createNode("base|mesh", "mesh") obasemeshinst = obase.addInstancedChild(basemesh) duplmesh = obasemeshinst.duplicate("newmeshname") # is a separate copy ! assert duplmesh != obasemeshinst dupltrans = base.duplicate("duplbase") baseduplmesh = dupltrans.childrenByType(nt.Mesh)[0] assert baseduplmesh != basemesh # its a separate copy
def test_duplicateInstances( self ): base = nt.createNode( "base", "transform" ) obase = nt.createNode( "obase", "transform" ) basemesh = nt.createNode( "base|mesh", "mesh" ) obasemeshinst = obase.addInstancedChild( basemesh ) duplmesh = obasemeshinst.duplicate( "newmeshname" ) # is a separate copy ! assert duplmesh != obasemeshinst dupltrans = base.duplicate( "duplbase" ) baseduplmesh = dupltrans.childrenByType( nt.Mesh )[0] assert baseduplmesh != basemesh # its a separate copy
def test_removeChild(self): base = nt.createNode("base" , "transform") trans = nt.createNode("base|trans", "transform") mesh = nt.createNode("base|mesh", "mesh") for item in [trans, mesh]: removeditem = base.removeChild(item, allowZeroParents=True) # PATHS ARE INVALID NOW - object is nowhere to be found assert not removeditem.isValid() and removeditem.isAlive() cmds.undo() assert removeditem.isValid() and removeditem.isAlive()
def test_removeChild( self ): base = nt.createNode( "base" , "transform" ) trans = nt.createNode( "base|trans", "transform" ) mesh = nt.createNode( "base|mesh", "mesh" ) for item in [ trans, mesh ]: removeditem = base.removeChild( item, allowZeroParents=True ) # PATHS ARE INVALID NOW - object is nowhere to be found assert not removeditem.isValid() and removeditem.isAlive() cmds.undo() assert removeditem.isValid() and removeditem.isAlive()
def test_dagPathVSMobjects( self ): node = nt.createNode( "parent|middle|child", "transform" ) nodem = nt.Node( "parent|middle" ) duplnodemiddle = nodem.duplicate( "middle1" ) instnode = duplnodemiddle.addInstancedChild( node ) assert instnode.object() == node.object() # compare mobject assert instnode != node # compare dag paths path = instnode.dagPath( ) childm1 = nt.Node( "parent|middle1|child" ) # if it didnt work, he would have returned a "|parent|middle|child" assert "|parent|middle1|child" == str(childm1) npath = node.dagPath( ) ipath = instnode.dagPath( ) assert npath != ipath assert node.object() == instnode.object() # same object after all # if an MObject is passed in, it should still work assert node == instnode.object() # using an attribute would create a DagNode which corresponds to the first path assert not node != instnode.wm.mwrappedNode() assert node == instnode.wm.mwrappedNode()
def test_displaySettings(self): mrvmaya.Scene.new(force = 1) mesh = nt.createNode("a1|b1|c1|d1|mesh", "mesh") mesh.tmp.msetInt(1) # TEMPLATE ########## assert mesh.isTemplate() cmds.undo() assert not mesh.isTemplate() a1 = mesh.root() a1.v.msetInt(0) # VISIBLE ######### assert not mesh.isVisible() cmds.undo() assert mesh.isVisible() # DRAWING OVERRIDES ################### a1.do.mchildByName('ove').msetInt(1) a1.do.mchildByName('ovdt').msetInt(2) assert mesh.displayOverrideValue('ovdt') == 2 cmds.undo() cmds.undo() assert mesh.displayOverrideValue('ovdt') == None
def test_dagPathVSMobjects(self): node = nt.createNode("parent|middle|child", "transform") nodem = nt.Node("parent|middle") duplnodemiddle = nodem.duplicate("middle1") instnode = duplnodemiddle.addInstancedChild(node) assert instnode.object() == node.object() # compare mobject assert instnode != node # compare dag paths path = instnode.dagPath() childm1 = nt.Node("parent|middle1|child") # if it didnt work, he would have returned a "|parent|middle|child" assert "|parent|middle1|child" == str(childm1) npath = node.dagPath() ipath = instnode.dagPath() assert npath != ipath assert node.object() == instnode.object() # same object after all # if an MObject is passed in, it should still work assert node == instnode.object() # using an attribute would create a DagNode which corresponds to the first path assert not node != instnode.wm.mwrappedNode() assert node == instnode.wm.mwrappedNode()
def test_displaySettings( self ): mrvmaya.Scene.new( force = 1 ) mesh = nt.createNode( "a1|b1|c1|d1|mesh", "mesh" ) mesh.tmp.msetInt( 1 ) # TEMPLATE ########## assert mesh.isTemplate() cmds.undo() assert not mesh.isTemplate() a1 = mesh.root() a1.v.msetInt( 0 ) # VISIBLE ######### assert not mesh.isVisible( ) cmds.undo() assert mesh.isVisible( ) # DRAWING OVERRIDES ################### a1.do.mchildByName('ove').msetInt( 1 ) a1.do.mchildByName('ovdt').msetInt( 2 ) assert mesh.displayOverrideValue( 'ovdt' ) == 2 cmds.undo() cmds.undo() assert mesh.displayOverrideValue( 'ovdt' ) == None
def test_storageAttributeHanlding(self): mrvmaya.Scene.new(force=True) snode = nt.createNode("storage", "storageNode") # autocreate off self.failUnlessRaises(AttributeError, snode.pythonData, "test") data = snode.masterPlug() val = snode.pythonData("test", autoCreate=True) oval = snode.pythonData("othertest", autoCreate=True) assert not oval.isReferenced() assert data.length() == 2 # have two right now, no prefix assert len(snode.dataIDs()) == 2 # check flags plug fplug = snode.storagePlug("test", snode.kFlags) assert fplug.asInt() == 0 fplug.msetInt(5) assert fplug.asInt() == 5 # CLEAR EMPTY DATA ###################### snode.clearData("test") # PREFIXES ############ snode.setDataPrefix("prefix") # must create new one pval = snode.pythonData("othertest", autoCreate=True) assert data.length() == 3 assert pval._plug.mparent().mchildByName("id").asString() == "prefixothertest" # now that we have a prefix, we only see prefixed attributes assert len(snode.dataIDs()) == 1 # STORAGE PLUGS (MAIN PLUG) # contains connection plug too mainplug = snode.findStoragePlug("othertest") assert mainplug == pval._plug.mparent() # attribute prefix assert snode.attributePrefix() == "" attr_prefix = "attr_prefix_" snode.addAttribute(createStorageAttribute(PyPickleData.kPluginDataId, name_prefix=attr_prefix)) snode.setAttributePrefix(attr_prefix) assert snode.masterPlug().length() == 0 snode.setAttributePrefix("") assert snode.masterPlug().length() == data.length() # CONNECTION PLUGS ################### persp = nt.Node("persp") conarray = mainplug.mchildByName("dmsg") for c in range(10): nextplug = conarray.elementByLogicalIndex(c) persp.message.mconnectTo(nextplug) assert persp.message.misConnectedTo(nextplug) assert conarray.length() == 10 assert len(persp.message.moutputs()) == 10
def test_dependnode_getitem(self): mesh = nt.createNode("p1|p2|mesh", "mesh") assert len(list(mesh.iterParents())) == 2 p2 = mesh.parent() p1 = p2.parent() assert mesh[-1] == p2 assert mesh[-2] == p1 self.failUnlessRaises(IndexError, mesh.__getitem__, -3)
def test_dependnode_getitem( self ): mesh = nt.createNode( "p1|p2|mesh", "mesh" ) assert len( list( mesh.iterParents() ) ) == 2 p2 = mesh.parent() p1 = p2.parent() assert mesh[-1] == p2 assert mesh[-2] == p1 self.failUnlessRaises( IndexError, mesh.__getitem__, -3 )
def test_instanceTraversal(self): base = nt.createNode("base", "transform") obase = nt.createNode("obase", "transform") abase = nt.createNode("abase", "transform") bases = (base, obase, abase) trans = nt.createNode("trans", "transform") shape = nt.createNode("meshtrans|mesh", "mesh") instances = (trans, shape) # create instances for inst in instances: for b in bases: b.addInstancedChild(inst) # INSTANCE TRAVERSAL for inst in instances: assert inst.instanceCount(False) == 4 assert inst == inst.instance(inst.instanceNumber()) for instinst in inst.iterInstances(excludeSelf = True): assert instinst != inst foundself = False for instinst in inst.iterInstances(excludeSelf = False): if instinst == inst: foundself = True assert foundself base.removeChild(inst) # remove one inst assert inst.instanceCount(False) == 3 base.addInstancedChild(inst) # readd it # END for each instance path # END for each instanced node # TRAVERSE NON-INSTANCED - should have one or 0 assert len(list((base.iterInstances(excludeSelf = True)))) == 0 assert len(list((base.iterInstances(excludeSelf = False)))) == 1 # TEST DIRECT VS INDIRECT INSTANCES baseinst = base.addParent(obase) assert base.instanceCount(False) == 2 assert trans.instanceCount(False) != trans.instanceCount(True) # iteration is always over all instances assert len(list((trans.iterInstances(excludeSelf=False)))) == trans.instanceCount(True)
def test_instanceTraversal( self ): base = nt.createNode( "base", "transform" ) obase = nt.createNode( "obase", "transform" ) abase = nt.createNode( "abase", "transform" ) bases = ( base, obase, abase ) trans = nt.createNode( "trans", "transform" ) shape = nt.createNode( "meshtrans|mesh", "mesh" ) instances = ( trans, shape ) # create instances for inst in instances: for b in bases: b.addInstancedChild( inst ) # INSTANCE TRAVERSAL for inst in instances: assert inst.instanceCount( False ) == 4 assert inst == inst.instance( inst.instanceNumber( ) ) for instinst in inst.iterInstances( excludeSelf = True ): assert instinst != inst foundself = False for instinst in inst.iterInstances( excludeSelf = False ): if instinst == inst: foundself = True assert foundself base.removeChild( inst ) # remove one inst assert inst.instanceCount( False ) == 3 base.addInstancedChild( inst ) # readd it # END for each instance path # END for each instanced node # TRAVERSE NON-INSTANCED - should have one or 0 assert len( list(( base.iterInstances( excludeSelf = True ) )) ) == 0 assert len( list(( base.iterInstances( excludeSelf = False ) )) ) == 1 # TEST DIRECT VS INDIRECT INSTANCES baseinst = base.addParent( obase ) assert base.instanceCount( False ) == 2 assert trans.instanceCount( False ) != trans.instanceCount( True ) # iteration is always over all instances assert len( list( ( trans.iterInstances(excludeSelf=False))) ) == trans.instanceCount( True )
def _createNodeFromName( self, name ): """:return: newly created maya node named 'name', using the respective type depending on its path ( with pipe or without""" nodetype = None if '|' in name: # name decides whether dag or dep node is created nodetype = random.choice( self.dagtypes ) else: nodetype = random.choice( self.deptypes ) return nt.createNode( name, nodetype, renameOnClash=True )
def create( cls, name="animationHandle", **kwargs ): """:return: New instance of our type providing the ``AnimationHandle`` interface :param kwargs: Passed to ``createNode`` method of mrv""" mynode = nt.createNode(name, "network", **kwargs) # add our custom attribute attr = nt.TypedAttribute.create(cls._l_connection_info_attr, cls._s_connection_info_attr, nt.api.MFnData.kStringArray, nt.StringArrayData.create(list())) mynode.addAttribute(attr) return cls(mynode.object())
def test_objectExistance(self): depnode = nt.createNode("node", "facade") assert nt.objExists(str(depnode)) # TEST DUPLICATION duplnode = depnode.duplicate() assert duplnode.isValid() copy2 = depnode.duplicate("name2") assert str(copy2) == "name2" # NOTE: currently undo is not opetional dagnode = nt.createNode("parent|node", "mesh") assert nt.objExists(str(dagnode)) # must clash with dg node (in maya, dg nodes will block names of dag node leafs !) self.failUnlessRaises(NameError, nt.createNode, "parent|node|node", "mesh", renameOnClash=False) # same clash occours if dag node exists first dagnode = nt.createNode("parent|othernode", "transform") self.failUnlessRaises(NameError, nt.createNode, "othernode", "facade", renameOnClash=False)
def test_objectExistance( self ): depnode = nt.createNode( "node", "facade" ) assert nt.objExists( str( depnode ) ) # TEST DUPLICATION duplnode = depnode.duplicate( ) assert duplnode.isValid( ) copy2 = depnode.duplicate( "name2" ) assert str( copy2 ) == "name2" # NOTE: currently undo is not opetional dagnode = nt.createNode( "parent|node", "mesh" ) assert nt.objExists( str( dagnode ) ) # must clash with dg node ( in maya, dg nodes will block names of dag node leafs ! ) self.failUnlessRaises( NameError, nt.createNode, "parent|node|node", "mesh", renameOnClash=False ) # same clash occours if dag node exists first dagnode = nt.createNode( "parent|othernode", "transform" ) self.failUnlessRaises( NameError, nt.createNode, "othernode", "facade", renameOnClash=False )
def test_keepWorldSpace( self ): g = nt.createNode( "g", "transform" ) t = nt.createNode( "t", "transform" ) t.setParent( g ) mainattrs = ( "t","s" ) subattrs = ( "x","y","z" ) count = 0.0 for ma in mainattrs: for sa in subattrs: getattr( g, ma ).mchildByName(ma+sa).msetFloat(count) count += 1.0 # END for each sa # END for each ma # REPARENT TO WORLD ################### t = t.reparent( None, keepWorldSpace = 1 ) count = 0.0 for ma in mainattrs: for sa in subattrs: value = t.findPlug(ma+sa).asFloat( ) assert value == count count += 1.0 # END # END # undo - everything should be back to normal cmds.undo() self._checkIdentity( t ) cmds.redo() # REPARENT TO PARENT NODE ########################### t = t.setParent( g, keepWorldSpace = 1 ) self._checkIdentity( t )
def test_keepWorldSpace(self): g = nt.createNode("g", "transform") t = nt.createNode("t", "transform") t.setParent(g) mainattrs = ("t","s") subattrs = ("x","y","z") count = 0.0 for ma in mainattrs: for sa in subattrs: getattr(g, ma).mchildByName(ma+sa).msetFloat(count) count += 1.0 # END for each sa # END for each ma # REPARENT TO WORLD ################### t = t.reparent(None, keepWorldSpace = 1) count = 0.0 for ma in mainattrs: for sa in subattrs: value = t.findPlug(ma+sa).asFloat() assert value == count count += 1.0 # END # END # undo - everything should be back to normal cmds.undo() self._checkIdentity(t) cmds.redo() # REPARENT TO PARENT NODE ########################### t = t.setParent(g, keepWorldSpace = 1) self._checkIdentity(t)
def test_reparentAndInstances(self): mesh = nt.createNode("trans|mesh", "mesh") base = nt.createNode("base|subbase", "transform") obase = nt.createNode("obase|subbase2", "transform") rbase = nt.createNode("reparentBase", "transform") # test basic functions assert rbase.apiType() == api.MFn.kTransform assert rbase.hasFn(api.MFn.kTransform) baseinst = base.addInstancedChild(mesh) obaseinst = obase.addInstancedChild(mesh) # try to re-wrap the instanced items assert nt.Node(str(baseinst)) == baseinst assert nt.Node(str(obaseinst)) == obaseinst # use partial name assert nt.Node("subbase|mesh") == baseinst assert nt.Node("subbase2|mesh") == obaseinst assert mesh.isValid() and baseinst.isValid() and obaseinst.isValid() # assure we catch this possibly damaage self.failUnlessRaises(RuntimeError, mesh.reparent, rbase, raiseOnInstance=True) # instances are gone should be gone mesh = mesh.reparent(rbase, raiseOnInstance=False) assert mesh.isValid() and not baseinst.isValid() and not obaseinst.isValid() # try unparent meshtrans = mesh.transform() meshtrans.setParent(obase) assert meshtrans.parent() == obase meshtrans.unparent() assert meshtrans.parent() is None
def test_reparentAndInstances( self ): mesh = nt.createNode( "trans|mesh", "mesh" ) base = nt.createNode( "base|subbase", "transform" ) obase = nt.createNode( "obase|subbase2", "transform" ) rbase = nt.createNode( "reparentBase", "transform" ) # test basic functions assert rbase.apiType() == api.MFn.kTransform assert rbase.hasFn( api.MFn.kTransform ) baseinst = base.addInstancedChild( mesh ) obaseinst = obase.addInstancedChild( mesh ) # try to re-wrap the instanced items assert nt.Node( str( baseinst ) ) == baseinst assert nt.Node( str( obaseinst ) ) == obaseinst # use partial name assert nt.Node( "subbase|mesh" ) == baseinst assert nt.Node( "subbase2|mesh" ) == obaseinst assert mesh.isValid() and baseinst.isValid() and obaseinst.isValid() # assure we catch this possibly damaage self.failUnlessRaises( RuntimeError, mesh.reparent, rbase, raiseOnInstance=True ) # instances are gone should be gone mesh = mesh.reparent( rbase, raiseOnInstance=False ) assert mesh.isValid() and not baseinst.isValid() and not obaseinst.isValid() # try unparent meshtrans = mesh.transform() meshtrans.setParent(obase) assert meshtrans.parent() == obase meshtrans.unparent() assert meshtrans.parent() is None
def test_storageAttributeHanlding( self ): mrvmaya.Scene.new( force = True ) snode = nt.createNode( "storage", "storageNode" ) # autocreate off self.failUnlessRaises( AttributeError, snode.pythonData, "test" ) data = snode.dta val = snode.pythonData( "test", autoCreate=True ) oval = snode.pythonData( "othertest", autoCreate=True ) assert len( data ) == 2 # have two right now, no prefix assert len( snode.dataIDs() ) == 2 # CLEAR EMPTY DATA ###################### snode.clearData( "test" ) # PREFIXES ############ snode._attrprefix = "prefix" # must create new one pval = snode.pythonData( "othertest", autoCreate=True ) assert len( data ) == 3 assert pval._plug.mparent().mchildByName('id').asString() == "prefixothertest" # now that we have a prefix, we only see prefixed attributes assert len( snode.dataIDs() ) == 1 # STORAGE PLUGS ( MAIN PLUG ) # contains connection plug too mainplug = snode.findStoragePlug( "othertest" ) assert mainplug == pval._plug.mparent() # CONNECTION PLUGS ################### persp = nt.Node( "persp" ) conarray = mainplug.mchildByName('dmsg') for c in range( 10 ): nextplug = conarray.elementByLogicalIndex( c ) persp.message.mconnectTo(nextplug) assert persp.message.misConnectedTo(nextplug) assert len( conarray ) == 10 assert len( persp.message.moutputs() ) == 10
def test_create_nodes(self): nn = 1000 for node_type in ("network", "transform"): # CREATE NODES st = time.time() node_list = list() for number in xrange(nn): n = nt.createNode(node_type, node_type) node_list.append(n) # END for each node to created elapsed = time.time() - st print >>sys.stderr, "Created %i %s nodes in %f s ( %f nodes / s )" % (nn, node_type, elapsed, nn/elapsed) # RENAME st = time.time() for node in node_list: node.rename(node.basename()[:-1]) # END for each node to rename elapsed = time.time() - st print >>sys.stderr, "Renamed %i %s nodes in %f s ( %f nodes / s )" % (nn, node_type, elapsed, nn/elapsed)
def test_single_vs_multi_connetions(self): sn = nt.createNode("network1", "network") tn = nt.createNode("network2", "network") sn2 = nt.createNode("network3", "network") tn2 = nt.createNode("network4", "network") sn3 = nt.createNode("network5", "network") tn3 = nt.createNode("network6", "network") def pir(array, range_iter): for i in range_iter: yield array.elementByLogicalIndex(i) # END plugs in range utility # single connection r = range(5000) st = time.time() for source, dest in zip(pir(sn.a, r), pir(tn.ab, r)): source.mconnectTo(dest) # END for whole range elapsed = time.time() - st print >> sys.stderr, "Single-Connected %i different multi-plugs in %f s ( %f / s )" % ( len(r), elapsed, len(r) / elapsed) # multiconnect st = time.time() api.MPlug.mconnectMultiToMulti(izip(pir(sn2.a, r), pir(tn2.ab, r)), force=False) elapsed = time.time() - st print >> sys.stderr, "Multi-Connected %i different multi-plugs in %f s ( %f / s )" % ( len(r), elapsed, len(r) / elapsed) # multiconnect with force worstcase st = time.time() api.MPlug.mconnectMultiToMulti(izip(pir(sn.a, r), pir(tn2.ab, r)), force=True) elapsed = time.time() - st print >> sys.stderr, "Multi-Connected %i different multi-plugs with worstcase FORCE in %f s ( %f / s )" % ( len(r), elapsed, len(r) / elapsed) # multiconnect with force bestcase r = range(len(r), len(r) + len(r)) st = time.time() api.MPlug.mconnectMultiToMulti(izip(pir(sn3.a, r), pir(tn3.ab, r)), force=True) elapsed = time.time() - st print >> sys.stderr, "Multi-Connected %i different multi-plugs with bestcase FORCE in %f s ( %f / s )" % ( len(r), elapsed, len(r) / elapsed)
def test_create_nodes(self): # create all types of nodes, just individual samples, assure createNode # gets it right pe = nt.PointEmitter() assert pe.parent() is None # a shape with just a shortname works as well m = nt.createNode("myMesh", "mesh") mp = m.parent() assert isinstance(mp, nt.Transform) cmds.undo() cmds.undo() assert pe.isAlive() and not pe.isValid() assert mp.isAlive() and not mp.isValid() assert m.isAlive() and not m.isValid() cmds.redo() assert pe.isValid() cmds.redo() assert m.isValid() and mp.isValid()
def test_single_vs_multi_connetions(self): sn = nt.createNode("network1", "network") tn = nt.createNode("network2", "network") sn2 = nt.createNode("network3", "network") tn2 = nt.createNode("network4", "network") sn3 = nt.createNode("network5", "network") tn3 = nt.createNode("network6", "network") def pir(array, range_iter): for i in range_iter: yield array.elementByLogicalIndex(i) # END plugs in range utility # single connection r = range(5000) st = time.time() for source, dest in zip(pir(sn.a, r), pir(tn.ab, r)): source.mconnectTo(dest) # END for whole range elapsed = time.time() - st print >> sys.stderr, "Single-Connected %i different multi-plugs in %f s ( %f / s )" % (len(r), elapsed, len(r) / elapsed) # multiconnect st = time.time() api.MPlug.mconnectMultiToMulti(izip(pir(sn2.a, r), pir(tn2.ab, r)), force=False) elapsed = time.time() - st print >> sys.stderr, "Multi-Connected %i different multi-plugs in %f s ( %f / s )" % (len(r), elapsed, len(r) / elapsed) # multiconnect with force worstcase st = time.time() api.MPlug.mconnectMultiToMulti(izip(pir(sn.a, r), pir(tn2.ab, r)), force=True) elapsed = time.time() - st print >> sys.stderr, "Multi-Connected %i different multi-plugs with worstcase FORCE in %f s ( %f / s )" % (len(r), elapsed, len(r) / elapsed) # multiconnect with force bestcase r = range(len(r), len(r)+len(r)) st = time.time() api.MPlug.mconnectMultiToMulti(izip(pir(sn3.a, r), pir(tn3.ab, r)), force=True) elapsed = time.time() - st print >> sys.stderr, "Multi-Connected %i different multi-plugs with bestcase FORCE in %f s ( %f / s )" % (len(r), elapsed, len(r) / elapsed)
def test_dgiter( self ): trans = nt.createNode( "trans", "transform" ) mesh = nt.createNode( "trans|mesh", "mesh" ) gid = nt.createNode( "gid", "groupId" ) fac = nt.createNode( "fac", "facade" ) fac1 = nt.createNode( "fac1", "facade" ) oset = nt.createNode( "set", "objectSet" ) # one type id assert len( list( iterDgNodes( api.MFn.kFacade ) ) ) == 2 assert oset in iterDgNodes( api.MFn.kSet, asNode=1 ) # multiple type ids filteredNodes = list( iterDgNodes( api.MFn.kSet, api.MFn.kGroupId, asNode=1 ) ) for node in [ gid, oset ]: assert node in filteredNodes # asNode assert isinstance(iterDgNodes(asNode=0).next(), api.MObject) # predicate assert len(list(iterDgNodes(predicate=lambda n: False))) == 0
def test_general( self ): mrvmaya.Scene.new( force = True ) s1 = nt.createNode( "storage1", "storageNode" ) s2 = nt.createNode( "storage2", "storageNode" ) s1msg = s1.storagePlug( "s1", plugType = 1, autoCreate = True ) s2msg = s1.storagePlug( "s1", plugType = 1, autoCreate = True ) # connect the message attributes respectively def measurePlugConnection( msg, func, callNumberList ): """Call func of named operation msg number of times as in callNumberList""" for numcons in callNumberList: undoObj = undo.StartUndo() starttime = time.time() for i in xrange( numcons ): func( i ) elapsed = time.time( ) - starttime print >> sys.stderr, "%i %s in %f s ( %f / s )" % ( numcons, msg, elapsed, numcons / elapsed ) del( undoObj ) starttime = time.time() cmds.undo() undoelapsed = time.time() - starttime starttime = time.time() cmds.redo() redoelapsed = time.time() - starttime print >> sys.stderr, "UNDO / REDO Time = %f / %f ( %f * faster than initial creation )" % ( undoelapsed, redoelapsed, elapsed / max( redoelapsed, 0.001) ) # END for each amount of plugs to connct # END measure function conlist = [ 250, 1000, 2000, 4000 ] # CONNECT MULTI PLUGS ###################### multifunc = lambda i: s1msg.elementByLogicalIndex( i ).mconnectTo(s2msg.elementByLogicalIndex( i )) measurePlugConnection( "MULTI PLUG Connected", multifunc, conlist ) # CONNECT SINGLE PLUGS persp = nt.Node( "persp" ) front = nt.Node( "front" ) def singleFunc( i ): persp.message.mconnectTo(front.isHistoricallyInteresting) persp.message.mdisconnectFrom(front.isHistoricallyInteresting) measurePlugConnection( "SINGLE PLUGS Connected", singleFunc, conlist ) # SET AND GET ############## persp = nt.Node( "persp" ) perspshape = persp[0] plugs = [ persp.tx, perspshape.fl ] num_iterations = 2500 iterations = range( num_iterations ) undoObj = undo.StartUndo() starttime = time.time() for plug in plugs: for i in iterations: value = plug.asFloat() plug.msetFloat( value ) # END get set plug # END for each plug elapsed = time.time() - starttime del( undoObj ) total_count = num_iterations * len( plugs ) print >> sys.stderr, "Get/Set %i plugs %i times ( total = %i ) in %f ( %g / s )" % ( len( plugs ), num_iterations, total_count, elapsed, total_count / elapsed ) starttime = time.time() cmds.undo() undoelapsed = time.time() - starttime starttime = time.time() cmds.redo() redoelapsed = time.time() - starttime print >> sys.stderr, "UNDO / REDO Time = %f / %f ( %f * faster than initial set/get )" % ( undoelapsed, redoelapsed, elapsed / max( redoelapsed, 0.001) )
def test_storageSetHandling( self ): mrvmaya.Scene.new( force = True ) snode = nt.createNode( "storage", "storageNode" ) # SIMPLE SET did = "objset" # error checking objset = snode.objectSet( did, 0, autoCreate = True ) assert isinstance( objset, nt.ObjectSet ) assert len(snode.setsByID(did)) == 1 # does not exist anymore cmds.undo() self.failUnlessRaises( AttributeError, snode.objectSet, did, 0, autoCreate = False ) # objset should be valid again cmds.redo() assert objset.isValid() and objset.isAlive() # del set snode.deleteObjectSet( did, 0 ) assert not objset.isValid() and objset.isAlive() self.failUnlessRaises( AttributeError, snode.objectSet, did, 0, False ) cmds.undo() assert objset.isValid() assert snode.objectSet(did, 0, False) == objset cmds.redo() assert not objset.isValid() self.failUnlessRaises( AttributeError, snode.objectSet, did, 0, False ) cmds.undo() # undo deletion after all assert objset.isValid() assert snode.objectSet(did, 0, False) == objset # SIMPLE OBJSET OPERATIONS # MULTIPLE SETS # PARTITION HANDLING ####################### partition = snode.setPartition( did, True ) assert snode.partition( did ) is not None cmds.undo() assert snode.partition( did ) is None cmds.redo() # set is available again # delete the single set we have, partition should be gone as well snode.deleteObjectSet( did, 0 ) assert not partition.isValid() cmds.undo() assert partition.isValid() # disable partition snode.setPartition( did, False ) assert snode.isAlive() and snode.isValid() # recently it would be deleted assert snode.partition( did ) is None snode.setPartition( did, True ) # new set, check partition oset = snode.objectSet( did, 1, autoCreate = 1 ) assert isinstance( oset, nt.ObjectSet ) assert len( oset.partitions() ) == 1 assert oset.partitions()[0] == snode.partition( did ) cmds.undo() assert len( oset.partitions() ) == 0 cmds.redo() # set is in multiple partitions, some from us, some from the user myprt = nt.createNode( "mypartition", "partition" ) myprt.addSets( oset ) assert myprt != snode.partition( did ) snode.setPartition( did, False ) assert myprt.sets( )[0] == oset assert len( oset.partitions() ) == 1 # undo / redo cmds.undo() assert len( oset.partitions() ) == 2 cmds.redo() assert len( oset.partitions() ) == 1
def test_storagePickleData( self ): tmpdir = make_path( tempfile.gettempdir() ) def setTestValue( mydict ): mydict['string'] = "hello world" mydict[1] = 3.0 mydict["list"] = ["this", 2, 45.0] def checkTestValue( self, mydict ): sval = mydict.get( "string" ) assert sval == "hello world" fval = mydict.get( 1 ) assert fval == 3.0 lval = mydict.get( "list" ) assert len( lval ) == 3 def fix_ascii_file(filepath): """Unfortunately, on windows and osx and maya2011, ascii's tend to corrupt themselves by writing ',' into floats which should be a '.'. Could be something related to the locale too. Nonetheless, we have to fix it and do a stupid find a replace""" if filepath.ext() != '.ma': return tmpfile = make_path(tempfile.mktemp()) ofh = open(tmpfile, 'wb') for line in open(filepath): ofh.write(line.replace(',', '.')) # END for each line ofh.close() filepath.remove() tmpfile.move(filepath) did = "test" for filetype in [ ".ma", ".mb" ]: mrvmaya.Scene.new( force = True ) # BASIC DATA CREATION AND EDITING #################################### storagenode = nt.createNode( "storage", "storageNode" ) refcomparator = nt.createNode( "trans", "transform" ) pyval = storagenode.pythonData( did, autoCreate = True ) # adjust the value - will be changed in place setTestValue( pyval ) # SAVE AND LOAD ! ################# # ascii and binary ( including reference test ) filepath = tmpdir / ( "storagetest" + filetype ) mrvmaya.Scene.save( filepath ) fix_ascii_file(filepath) # reload mrvmaya.Scene.open( filepath, force=True ) # get and test data storagenode = nt.Node( "storage" ) pyvalloaded = storagenode.pythonData( did, autoCreate = False ) checkTestValue( self, pyvalloaded ) # CLEAR NON-EMPTY DATA WITH UNDO ################################## storagenode.clearData( did ) pydatacleared = storagenode.pythonData( did, autoCreate =False ) assert not pydatacleared.has_key( "string" ) cmds.undo() pydataundone = storagenode.pythonData( did, autoCreate =False ) assert pydataundone.has_key( "string" ) # CREATE REFERENCE ################## mrvmaya.Scene.new( force = True ) mrvmaya.ref.createReference( filepath, namespace="referenced" ) refstoragenode = nt.Node( "referenced:storage" ) refcomparator = nt.Node( "referenced:trans" ) pyval = refstoragenode.pythonData( did ) # adjust values pyval[ "refchange" ] = "changed in reference" refcomparator.tx.msetFloat( 5.5 ) # save reference filewithrefpath = tmpdir / ( "refstoragetest" + filetype ) mrvmaya.Scene.save( filewithrefpath ) fix_ascii_file(filewithrefpath) mrvmaya.Scene.open( filewithrefpath, force = True ) # check test value and the newly written one refstoragenode = nt.Node( "referenced:storage" ) pyval = refstoragenode.pythonData( did ) checkTestValue( self, pyval ) sval = pyval[ 'refchange' ] assert sval == "changed in reference" # DUPLICATION ############### for is_shallow in range( 2 ): duplicate = refstoragenode.duplicate( shallow = is_shallow ) ddata = duplicate.pythonData( did ) data = refstoragenode.pythonData( did ) checkTestValue( self, ddata ) # assure that its a real copy , not just something shallow if not is_shallow: data[ 'other' ] = 2 assert not ddata.has_key( 'other' )
def test_setOperations( self ): """byroniom.maya.nt.sets: unions, intersections, difference, overloaded ops""" memberlist = self._getMemberList( ) s3 = nt.createNode( "anotherObjectSet", "objectSet" ) s = nt.ObjectSet() s.clear() s.addMembers( memberlist ) side = nt.Node( "side" ) s2 = nt.createNode( "memberSet2", "objectSet" ) s2.addMember( side ) # UNION ######## # with set sellist = s.union( s2 ) assert sellist.length() == len( memberlist ) + 1 # with sellist - will create temp set sellist = s.union( s2.members() ) assert sellist.length() == len( memberlist ) + 1 assert not nt.objExists( "set4" ) # tmp set may not exist # with multiple object sets s.union( [ s2, s3 ] ) list( s.iterUnion( s2 ) ) # INTERSECTION ############### fewmembers = memberlist[:3] s2.addMembers( fewmembers ) # add 0 members s2.addMembers( list() ) # with set sellist = s.intersection( s2 ) assert sellist.length() == len( fewmembers ) # with sellist sellist = s.intersection( fewmembers ) assert sellist.length() == len( fewmembers ) # with multi sets s3.addMembers( fewmembers ) sellist = s.intersection( [ s2, s3 ] ) assert sellist.length() == len( fewmembers ) list( s.iterIntersection( s2 ) ) # DIFFERENCE ############# # with set s2.removeMember( side ) sellist = s.difference( s2 ) assert s.members().length() - s2.members().length() == sellist.length() # with objects sellist = s.difference( list( s2.iterMembers() ) ) assert s.members().length() - s2.members().length() == sellist.length() # with sellist sellist = s.difference( s2.members() ) # with multiple sets s3.clear() s3.addMember( nt.Node( "front" ) ) sellist = s.difference( [ s2, s3 ] ) assert len( list( s.iterDifference( [ s2, s3 ] ) ) ) == s.difference( [ s2, s3 ] ).length() assert s.members().length() - s2.members().length() - s3.members().length() == sellist.length()
def test_wrapDagNode( self ): mesh = nt.createNode( "parent|mesh", "mesh" ) parent = mesh.parent( ) # simple rename mesh.rename( "fancymesh" ) # simple dupl test duplbase = nt.createNode( "parent|this|other|duplbase", "mesh" ) transcopy = duplbase.transform( ).duplicate() copy = duplbase.duplicate( "parent|this|other|duplcopy" ) assert copy != duplbase assert str( copy ) != str( duplbase ) assert str( copy ) == "|parent|this|other|duplcopy" # TEST ADDITIONAL OPTIONS for i in range( 1,3 ): ocopy = duplbase.duplicate( ) assert str( ocopy ) == str( duplbase ) + str( i ) ocopy = duplbase.duplicate( newTransform=1 ) assert ocopy.basename( ) == duplbase.basename() assert str( ocopy.parent() ) == str( duplbase.parent() ) + str( i + 1 ) # undo both duplications and redo # CRASHES MAYA AFTER REDO # and if someone tries to access an object already created #cmds.undo() #cmds.undo() #assert duplbase.isValid() #cmds.redo() #cmds.redo() # END for each copy # simple reparent otherparent = nt.createNode( "oparent", "transform" ) mesh.reparent( otherparent ) # REPARENT UNDO TEST cmds.undo() assert mesh.parent() == parent cmds.redo() assert mesh.parent() == otherparent # REPARENT RENAME CLASH origmesh = nt.createNode( "parent|fancymesh", "mesh" ) # "|parent|fancymesh" self.failUnlessRaises( RuntimeError, mesh.reparent, parent , renameOnClash = False ) # RENAME CLASH DAG NODE othermesh = nt.createNode( "parent|mesh", "mesh" ) self.failUnlessRaises( RuntimeError, origmesh.rename, "mesh", renameOnClash = False ) # now it works othermesh.rename( "mesh", renameOnClash = True ) assert othermesh.basename( ) == "mesh" # shape under root self.failUnlessRaises( RuntimeError, mesh.reparent, None ) # REPARENT AGAIN # should just work as the endresult is the same mesh.reparent( otherparent ) # it will also trigger a new undo event, so undo will react as it should mesh.reparent( otherparent ) # "|otherparent|fancymesh" # REPARENT UNDER SELF self.failUnlessRaises( RuntimeError, mesh.reparent, mesh ) # reparent transform to world wtrans = nt.createNode( "parent2|worldtrans", "transform" ) parent = nt.Node( "parent2" ) oparent = nt.createNode( "oparent2", "transform" ) wtrans = wtrans.reparent( None ) wtransnewparent = wtrans.setParent( parent ) assert wtrans == wtransnewparent assert wtransnewparent.instanceCount( 1 ) == 1 wtransnewparent.addParent( oparent ) assert wtransnewparent.instanceCount( 1 ) == 2 wtransnewparent.removeParent( oparent ) assert wtrans.instanceCount( 1 ) == 1 # OBJECT NAVIGATION ####################### # TODO: navigate the object properly # DUPLICATE ( Dag only ) ######################### newmesh = mesh.duplicate( "|duplparent|duplmesh" ) assert str( newmesh ) == "|duplparent|duplmesh" self.failUnlessRaises( RuntimeError, mesh.duplicate, "|duplparent2|doesntexistns:duplmesh", autocreateNamespace = False ) assert newmesh != mesh instbase = nt.createNode( "|duplparent2|newnamespace:instmesh", "transform" ) meshinst = instbase.addInstancedChild( mesh ) meshinstname = str( meshinst ) # UNDO DUPLICATE ################# cmds.undo() # this object will end up pointing to the same object , as it came from, use string test assert not nt.objExists( meshinstname ) cmds.redo() cmds.undo() cmds.redo() assert meshinst != mesh assert meshinst.isAlive() and meshinst.isValid() and str( meshinst ) == meshinstname # Duplicate TRANSFORM ( just a name given ) # dag paths should be different although object is the same mesh = nt.createNode( "|parent|mybeautifuluniquemeshname", "mesh" ) meshassert = nt.createNode( "|parent|mesh", "mesh" ) meshself = nt.Node( "|parent|mybeautifuluniquemeshname" ) assert mesh == meshself # connect it, to track the instance by connection persp = nt.Node( "persp" ) perspplug = persp.t.mchildByName('tx') triplug = meshself.maxTriangles perspplug.mconnectTo(triplug) # target does exist # this is blocking the target instance name with an incorrect type nt.createNode( "parent|this|mybeautifuluniquemeshname", "transform" ) self.failUnlessRaises( RuntimeError, mesh.duplicate, "|parent|this" ) # if the path is too short ... self.failUnlessRaises( NameError, mesh.duplicate, str( mesh.transform() ) ) self.failUnlessRaises( NameError, mesh.parent().duplicate, '|' ) meshinstname = mesh.transform().fullChildName( "newns:meshinst" ) assert isinstance( meshinst, nt.Mesh )
def test_memberHandling( self ): s = nt.createNode( "memberSet", "objectSet" ) # ADD/REMOVE SINGLE MEMBER #################### # add Node ( dgnode ) memberlist = self._getMemberList( ) for i,member in enumerate( memberlist ): s.addMember( member ) assert s.members( ).length() == i+1 assert s.isMember( member ) cmds.undo() assert s.members( ).length() == i cmds.redo() # end for each member # clear the set by undoing it all for i in range( len( memberlist ) ): cmds.undo() assert s.members().length() == 0 # get it back for i in range( len( memberlist ) ): cmds.redo() assert s.members().length() == len( memberlist ) # MULTI-MEMBER UNDO/REDO ########################## s.removeMembers( memberlist ) assert s.members().length() == 0 cmds.undo() assert s.members().length() == len( memberlist ) cmds.redo() assert s.members().length() == 0 # add members again s.addMembers( memberlist ) assert s.members().length() == len( memberlist ) cmds.undo() assert s.members().length() == 0 cmds.redo() assert s.members().length() == len( memberlist ) # remove all members for i,member in enumerate( memberlist ): s.removeMember( member ) assert s.members().length() == 0 # ADD/REMOVE MULTIPLE MEMBER ###################### # add node list s.addMembers( memberlist ) assert s.members().length() == len( memberlist ) s.clear() assert s.members().length() == 0 # Add selection listx sellist = nt.toSelectionList( memberlist ) s.addMembers( sellist ) assert s.members().length() == sellist.length() # remove members from sellist s.removeMembers( sellist ) assert s.members().length() == 0 cmds.undo() assert s.members().length() == sellist.length() cmds.redo() assert s.members().length() == 0 # test smart add s.add(sellist) assert len(s) == len(sellist) single_item = sellist.mtoIter().next() s.add(single_item) assert len(s) == len(sellist) s.discard(single_item) assert single_item not in s s.discard(sellist.mtoList()) assert len(s) == 0 # TEST CLEAR ############# s.addMembers( sellist ) assert s.members().length() == sellist.length() s.clear() assert s.members().length() == 0 cmds.undo() assert s.members().length() == sellist.length() # USING SETMEMBERS ######################## members = self._getMemberList() # replace s.setMembers( members[0:2], 0 ) assert s.members().length() == 2 # add s.setMembers( members[-2:-1], 1 ) assert s.members().length() == 3 # remove s.setMembers( members[0:2], 2 ) assert s.members().length() == 1 cmds.undo() assert s.members().length() == 3 # TEST SET PROTOCOLS #################### assert len(s) == 3 assert [ m for m in s ] == s.members().mtoList() assert iter(s).next() in s
def test_childEditing(self): base = nt.createNode("basenode", "transform") obase = nt.createNode("otherbasenode", "transform") trans = nt.createNode("trans", "transform") otrans = nt.createNode("parent|trans", "transform") mesh = nt.createNode("meshparent|meshshape", "mesh") curve = nt.createNode("nurbsparent|ncurve", "nurbsCurve") itemlist = [trans, mesh, curve] instlist = list() # MULTIPLE ADDS #################### # Returns the same instance - its what the user wants for item in itemlist: assert item.instanceCount(0) == 1 inst = base.addInstancedChild(item) assert base.addInstancedChild(item) == inst assert item.instanceCount(0) == 2 assert item != inst and inst.isValid() and item.isValid() instlist.append(inst) # UNDO TEST # undo basemesh cmds.undo() assert not inst.isValid() and inst.isAlive() cmds.redo() assert inst.isValid() and inst.isAlive() # END for each object including undo/redo # KEEP PARENT FALSE - USE INSTANCES # TODO: this test needs a redo - the original purpose got lost when # the addChild method has been changed, additionally it needs to be # better documented as this instancing stuff is not easily understood if # one just sees the code for orig,inst in zip(itemlist, instlist): assert orig.object() == inst.object() and orig != inst ninst = obase.addChild(inst, keepExistingParent=False) # # duplicate adds are not problem, but it can't be tested as the inst is already invalid # assert obase.addChild(inst, keepExistingParent=False) == ninst assert not inst.isValid() assert ninst.isValid() and ninst.isAlive() assert orig.isValid() # original may not be influenced by that operation # undo / redo cmds.undo() assert orig.isValid() assert not ninst.isValid() assert inst.isValid() cmds.redo() assert not inst.isValid() and orig.isValid() and ninst.isValid() # END for each instance # RENAME ON CLASH = False self.failUnlessRaises(RuntimeError, obase.addChild, otrans, renameOnClash = False) # RENAME ON CLASH = True otransname = str(otrans) renamedtrans = obase.addChild(otrans, renameOnClash = True) assert renamedtrans.isValid() renamedname = str(renamedtrans) assert renamedname != otransname cmds.undo() assert nt.objExists(otransname) and not nt.objExists(renamedname) cmds.redo()
def test_general(self): mrvmaya.Scene.new(force=True) s1 = nt.createNode("storage1", "storageNode") s2 = nt.createNode("storage2", "storageNode") s1msg = s1.storagePlug("s1", plugType=1, autoCreate=True) s2msg = s1.storagePlug("s1", plugType=1, autoCreate=True) # connect the message attributes respectively def measurePlugConnection(msg, func, callNumberList): """Call func of named operation msg number of times as in callNumberList""" for numcons in callNumberList: undoObj = undo.StartUndo() starttime = time.time() for i in xrange(numcons): func(i) elapsed = time.time() - starttime print >> sys.stderr, "%i %s in %f s ( %f / s )" % ( numcons, msg, elapsed, numcons / elapsed) del (undoObj) starttime = time.time() cmds.undo() undoelapsed = time.time() - starttime starttime = time.time() cmds.redo() redoelapsed = time.time() - starttime print >> sys.stderr, "UNDO / REDO Time = %f / %f ( %f * faster than initial creation )" % ( undoelapsed, redoelapsed, elapsed / max(redoelapsed, 0.001)) # END for each amount of plugs to connct # END measure function conlist = [250, 1000, 2000, 4000] # CONNECT MULTI PLUGS ###################### multifunc = lambda i: s1msg.elementByLogicalIndex(i).mconnectTo( s2msg.elementByLogicalIndex(i)) measurePlugConnection("MULTI PLUG Connected", multifunc, conlist) # CONNECT SINGLE PLUGS persp = nt.Node("persp") front = nt.Node("front") def singleFunc(i): persp.message.mconnectTo(front.isHistoricallyInteresting) persp.message.mdisconnectFrom(front.isHistoricallyInteresting) measurePlugConnection("SINGLE PLUGS Connected", singleFunc, conlist) # SET AND GET ############## persp = nt.Node("persp") perspshape = persp[0] plugs = [persp.tx, perspshape.fl] num_iterations = 2500 iterations = range(num_iterations) undoObj = undo.StartUndo() starttime = time.time() for plug in plugs: for i in iterations: value = plug.asFloat() plug.msetFloat(value) # END get set plug # END for each plug elapsed = time.time() - starttime del (undoObj) total_count = num_iterations * len(plugs) print >> sys.stderr, "Get/Set %i plugs %i times ( total = %i ) in %f ( %g / s )" % ( len(plugs), num_iterations, total_count, elapsed, total_count / elapsed) starttime = time.time() cmds.undo() undoelapsed = time.time() - starttime starttime = time.time() cmds.redo() redoelapsed = time.time() - starttime print >> sys.stderr, "UNDO / REDO Time = %f / %f ( %f * faster than initial set/get )" % ( undoelapsed, redoelapsed, elapsed / max(redoelapsed, 0.001))
def test_wrapDagNode(self): mesh = nt.createNode("parent|mesh", "mesh") parent = mesh.parent() # simple rename mesh.rename("fancymesh") # simple dupl test duplbase = nt.createNode("parent|this|other|duplbase", "mesh") transcopy = duplbase.transform().duplicate() copy = duplbase.duplicate("parent|this|other|duplcopy") assert copy != duplbase assert str(copy) != str(duplbase) assert str(copy) == "|parent|this|other|duplcopy" # TEST ADDITIONAL OPTIONS for i in range(1,3): ocopy = duplbase.duplicate() assert str(ocopy) == str(duplbase) + str(i) ocopy = duplbase.duplicate(newTransform=1) assert ocopy.basename() == duplbase.basename() assert str(ocopy.parent()) == str(duplbase.parent()) + str(i + 1) # undo both duplications and redo # CRASHES MAYA AFTER REDO # and if someone tries to access an object already created #cmds.undo() #cmds.undo() #assert duplbase.isValid() #cmds.redo() #cmds.redo() # END for each copy # simple reparent otherparent = nt.createNode("oparent", "transform") mesh.reparent(otherparent) # REPARENT UNDO TEST cmds.undo() assert mesh.parent() == parent cmds.redo() assert mesh.parent() == otherparent # REPARENT RENAME CLASH origmesh = nt.createNode("parent|fancymesh", "mesh") # "|parent|fancymesh" self.failUnlessRaises(RuntimeError, mesh.reparent, parent , renameOnClash = False) # RENAME CLASH DAG NODE othermesh = nt.createNode("parent|mesh", "mesh") self.failUnlessRaises(RuntimeError, origmesh.rename, "mesh", renameOnClash = False) # now it works othermesh.rename("mesh", renameOnClash = True) assert othermesh.basename() == "mesh" # shape under root self.failUnlessRaises(RuntimeError, mesh.reparent, None) # REPARENT AGAIN # should just work as the endresult is the same mesh.reparent(otherparent) # it will also trigger a new undo event, so undo will react as it should mesh.reparent(otherparent) # "|otherparent|fancymesh" # REPARENT UNDER SELF self.failUnlessRaises(RuntimeError, mesh.reparent, mesh) # reparent transform to world wtrans = nt.createNode("parent2|worldtrans", "transform") parent = nt.Node("parent2") oparent = nt.createNode("oparent2", "transform") wtrans = wtrans.reparent(None) wtransnewparent = wtrans.setParent(parent) assert wtrans == wtransnewparent assert wtransnewparent.instanceCount(1) == 1 wtransnewparent.addParent(oparent) assert wtransnewparent.instanceCount(1) == 2 wtransnewparent.removeParent(oparent) assert wtrans.instanceCount(1) == 1 # OBJECT NAVIGATION ####################### # TODO: navigate the object properly # DUPLICATE (Dag only) ######################### newmesh = mesh.duplicate("|duplparent|duplmesh") assert str(newmesh) == "|duplparent|duplmesh" self.failUnlessRaises(RuntimeError, mesh.duplicate, "|duplparent2|doesntexistns:duplmesh", autocreateNamespace = False) assert newmesh != mesh instbase = nt.createNode("|duplparent2|newnamespace:instmesh", "transform") meshinst = instbase.addInstancedChild(mesh) meshinstname = str(meshinst) # UNDO DUPLICATE ################# cmds.undo() # this object will end up pointing to the same object , as it came from, use string test assert not nt.objExists(meshinstname) cmds.redo() cmds.undo() cmds.redo() assert meshinst != mesh assert meshinst.isAlive() and meshinst.isValid() and str(meshinst) == meshinstname # Duplicate TRANSFORM (just a name given) # dag paths should be different although object is the same mesh = nt.createNode("|parent|mybeautifuluniquemeshname", "mesh") meshassert = nt.createNode("|parent|mesh", "mesh") meshself = nt.Node("|parent|mybeautifuluniquemeshname") assert mesh == meshself # connect it, to track the instance by connection persp = nt.Node("persp") perspplug = persp.t.mchildByName('tx') triplug = meshself.maxTriangles perspplug.mconnectTo(triplug) # target does exist # this is blocking the target instance name with an incorrect type nt.createNode("parent|this|mybeautifuluniquemeshname", "transform") self.failUnlessRaises(RuntimeError, mesh.duplicate, "|parent|this") # if the path is too short ... self.failUnlessRaises(NameError, mesh.duplicate, str(mesh.transform())) self.failUnlessRaises(NameError, mesh.parent().duplicate, '|') meshinstname = mesh.transform().fullChildName("newns:meshinst") assert isinstance(meshinst, nt.Mesh)
def test_createNodes( self ): names = ["hello","bla|world","this|world|here","that|this|world|here" ] nsnames = ["a:hello","blab|b:world","c:this|b:world","d:that|c:this|b:world|a:b:c:d:here"] types = [ "facade", "nurbsCurve", "nurbsSurface", "subdiv" ] # SIMPLE CREATION: Paths + nested namespaces for i in range( len( names ) ): ntype = types[i] newnode = nt.createNode( names[i], ntype ) assert isinstance( newnode, getattr( nt, capitalize( ntype ) ) ) assert newnode.isValid() and newnode.isAlive() # test undo cmds.undo() assert not newnode.isValid() and newnode.isAlive() cmds.redo() assert newnode.isValid() and newnode.isAlive() newnsnode = nt.createNode( nsnames[i], ntype ) assert isinstance( newnsnode, getattr( nt, capitalize( ntype ) ) ) assert newnsnode.isValid() and newnsnode.isAlive() # test undo cmds.undo() assert not newnsnode.isValid() and newnsnode.isAlive() cmds.redo() assert newnsnode.isValid() and newnsnode.isAlive() # END for each created object # EMPTY NAME and ROOT self.failUnlessRaises( RuntimeError, nt.createNode, '|', "facade" ) self.failUnlessRaises( RuntimeError, nt.createNode, '', "facade" ) # CHECK DIFFERENT ROOT TYPES depnode = nt.createNode( "blablub", "facade" ) self.failUnlessRaises( NameError, nt.createNode, "|blablub|:this", "transform", renameOnClash = False ) # DIFFERENT TYPES AT END OF PATH nt.createNode( "this|mesh", "mesh" ) self.failUnlessRaises( NameError, nt.createNode, "this|mesh", "nurbsSurface", forceNewLeaf = False ) # renameOnClash - it fails if the dep node exists first nt.createNode( "node", "facade" ) self.failUnlessRaises( NameError, nt.createNode, "this|that|node", "mesh", renameOnClash = False ) # obj exists should match dg nodes with dag node like path ( as they occupy the same # namespace after all assert nt.objExists( "|node" ) # it also clashes if the dg node is created after a dag node with the same name nt.createNode( "that|nodename", "mesh" ) self.failUnlessRaises( NameError, nt.createNode, "nodename", "facade", renameOnClash = False ) # it should be fine to have the same name in several dag levels though ! newmesh = nt.createNode( "parent|nodename", "transform" ) newmesh1 = nt.createNode( "parent|nodename|nodename", "mesh" ) newmesh2 = nt.createNode( "otherparent|nodename|nodename", "mesh" ) assert newmesh != newmesh1 assert newmesh1 != newmesh2 # FORCE NEW ############## oset = nt.createNode( "objset", "objectSet", forceNewLeaf = False ) newoset = nt.createNode( "objset", "objectSet", forceNewLeaf = True ) assert oset != newoset # would expect same set to be returned sameoset = nt.createNode( "objset", "objectSet", forceNewLeaf = False ) assert sameoset == oset # force new and dag paths newmesh3 = nt.createNode( "otherparent|nodename|nodename", "mesh", forceNewLeaf = True ) assert newmesh3 != newmesh2
def test_partitions(self): # one transform, two sets, one partition s1 = nt.createNode("ms1", "objectSet") s2 = nt.createNode("ms2", "objectSet") p = nt.createNode("p1", "partition") s3 = nt.createNode("ms3", "objectSet") s4 = nt.createNode("ms4", "objectSet") t = nt.createNode("my_trans", "transform") t2 = nt.createNode("my_trans2", "transform") p.addSets([s1, s2]) # Also adding sets ################ # Internally the check for added objects can use intersection operations # to see whether objects are actually in there - if there would not be # some notion of 'sets_are_members', it would take the members of sets as items for # intersection for o1, o2 in [(t, t2), (s3, s4)]: # SINGLE OBJECT ############### multiobj = [o1, o2] s1.addMember(o1) self.failUnlessRaises(nt.ConstraintError, s2.addMember, o1) # failure, as errors are not ignored s2.addMember(o1, ignore_failure=1) # ignore failure # FORCE s2.addMember(o1, force=1) assert s2.isMember(o1) # MULTIPLE OBJECTS ################### self.failUnlessRaises(nt.ConstraintError, s1.addMembers, multiobj) # fails as t is in s2 s1.addMembers([o2]) # works as t2 is not in any set yet assert s1.isMember(o2) # FORCE all objects into s1 s1.addMembers(multiobj, force=1) assert s1.intersection(multiobj, sets_are_members=1).length() == 2 # and once more assert isinstance(s1.clear(), nt.ObjectSet) s2.clear() for s in s1, s2: assert s.members().length() == 0 s1.addMembers(multiobj) self.failUnlessRaises(nt.ConstraintError, s2.addMembers, multiobj, force=False, ignore_failure=False) assert s2.members().length() == 0 s2.addMembers(multiobj, force=False, ignore_failure=1) assert s2.members().length() == 0 # now force it s2.addMembers(multiobj, force=1) assert s2.members().length() == 2 # END for each object # SHADER ASSIGNMENTS ###################### sphere = nt.Node(cmds.polySphere()[0])[0] cube = nt.Node(cmds.polyCube()[0])[0] multi = (sphere, cube) all_sets = sphere.connectedSets(setFilter=sphere.fSets) isg = all_sets[0] # initial shading group rp = isg.partitions()[0] # render partition assert str(isg).startswith("initial") snode = nt.createNode("mysg", "shadingEngine") snode.setPartition(rp, 1) self.failUnlessRaises(nt.ConstraintError, snode.addMember, sphere) self.failUnlessRaises(nt.ConstraintError, snode.addMembers, multi) # now force it in snode.addMembers(multi, force=1, ignore_failure=0) assert snode.members().length() == 2 assert snode.intersection(multi).length() == 2
def test_setOperations(self): """byroniom.maya.nt.sets: unions, intersections, difference, overloaded ops""" memberlist = self._getMemberList() s3 = nt.createNode("anotherObjectSet", "objectSet") s = nt.ObjectSet() s.clear() s.addMembers(memberlist) side = nt.Node("side") s2 = nt.createNode("memberSet2", "objectSet") s2.addMember(side) # UNION ######## # with set sellist = s.union(s2) assert sellist.length() == len(memberlist) + 1 # with sellist - will create temp set sellist = s.union(s2.members()) assert sellist.length() == len(memberlist) + 1 assert not nt.objExists("set4") # tmp set may not exist # with multiple object sets s.union([s2, s3]) list(s.iterUnion(s2)) # INTERSECTION ############### fewmembers = memberlist[:3] s2.addMembers(fewmembers) # add 0 members s2.addMembers(list()) # with set sellist = s.intersection(s2) assert sellist.length() == len(fewmembers) # with sellist sellist = s.intersection(fewmembers) assert sellist.length() == len(fewmembers) # with multi sets s3.addMembers(fewmembers) sellist = s.intersection([s2, s3]) assert sellist.length() == len(fewmembers) list(s.iterIntersection(s2)) # DIFFERENCE ############# # with set s2.removeMember(side) sellist = s.difference(s2) assert s.members().length() - s2.members().length() == sellist.length() # with objects sellist = s.difference(list(s2.iterMembers())) assert s.members().length() - s2.members().length() == sellist.length() # with sellist sellist = s.difference(s2.members()) # with multiple sets s3.clear() s3.addMember(nt.Node("front")) sellist = s.difference([s2, s3]) assert len(list(s.iterDifference([s2, s3]))) == s.difference([s2, s3 ]).length() assert s.members().length() - s2.members().length() - s3.members( ).length() == sellist.length()
def test_memberHandling(self): s = nt.createNode("memberSet", "objectSet") # ADD/REMOVE SINGLE MEMBER #################### # add Node ( dgnode ) memberlist = self._getMemberList() for i, member in enumerate(memberlist): s.addMember(member) assert s.members().length() == i + 1 assert s.isMember(member) cmds.undo() assert s.members().length() == i cmds.redo() # end for each member # clear the set by undoing it all for i in range(len(memberlist)): cmds.undo() assert s.members().length() == 0 # get it back for i in range(len(memberlist)): cmds.redo() assert s.members().length() == len(memberlist) # MULTI-MEMBER UNDO/REDO ########################## s.removeMembers(memberlist) assert s.members().length() == 0 cmds.undo() assert s.members().length() == len(memberlist) cmds.redo() assert s.members().length() == 0 # add members again s.addMembers(memberlist) assert s.members().length() == len(memberlist) cmds.undo() assert s.members().length() == 0 cmds.redo() assert s.members().length() == len(memberlist) # remove all members for i, member in enumerate(memberlist): s.removeMember(member) assert s.members().length() == 0 # ADD/REMOVE MULTIPLE MEMBER ###################### # add node list s.addMembers(memberlist) assert s.members().length() == len(memberlist) s.clear() assert s.members().length() == 0 # Add selection listx sellist = nt.toSelectionList(memberlist) s.addMembers(sellist) assert s.members().length() == sellist.length() # remove members from sellist s.removeMembers(sellist) assert s.members().length() == 0 cmds.undo() assert s.members().length() == sellist.length() cmds.redo() assert s.members().length() == 0 # test smart add s.add(sellist) assert len(s) == len(sellist) single_item = sellist.mtoIter().next() s.add(single_item) assert len(s) == len(sellist) s.discard(single_item) assert single_item not in s s.discard(sellist.mtoList()) assert len(s) == 0 # TEST CLEAR ############# s.addMembers(sellist) assert s.members().length() == sellist.length() s.clear() assert s.members().length() == 0 cmds.undo() assert s.members().length() == sellist.length() # USING SETMEMBERS ######################## members = self._getMemberList() # replace s.setMembers(members[0:2], 0) assert s.members().length() == 2 # add s.setMembers(members[-2:-1], 1) assert s.members().length() == 3 # remove s.setMembers(members[0:2], 2) assert s.members().length() == 1 cmds.undo() assert s.members().length() == 3 # TEST SET PROTOCOLS #################### assert len(s) == 3 assert [m for m in s] == s.members().mtoList() assert iter(s).next() in s
def test_createAddRemove( self ): set1 = nt.createNode( "set1", "objectSet" ) set2 = nt.createNode( "set2", "objectSet" ) set3 = nt.createNode( "set3", "objectSet" ) prt1 = nt.createNode( "partition1", "partition" ) prt2 = nt.createNode( "partition2", "partition" ) # SET PARTITION HANDLING ######################### assert len( set1.partitions( ) ) == 0 set1.setPartition( prt1, set1.kReplace ) assert len( set1.partitions() ) == 1 assert set1.partitions()[0] == prt1 # add same again set1.setPartition( prt1, set1.kAdd ) assert len( set1.partitions() ) == 1 # remove set1.setPartition( prt1, set1.kRemove ) assert len( set1.partitions( ) ) == 0 # remove again set1.setPartition( prt1, set1.kRemove ) # PARTITION MEMBER HANDLING # add multiple sets prt1.addSets( [ set1, set2 ] ) assert len( prt1.members() ) == 2 # add again prt1.addSets( [ set1, set2 ] ) prt1.removeSets( [ set1, set2] ) assert len( prt1.members() ) == 0 # remove again prt1.removeSets( [ set1, set2] ) prt2.addSets( [ set1, set2] ) # replace multiple prt2.replaceSets( [ set3 ] ) # set like methods prt2.add(set1) assert set1 in prt2 prt2.discard(set1) assert set1 not in prt2 # test partition protocols assert len(prt2) == len(prt2.members()) assert [ s for s in prt2 ] == prt2.members() assert set3 in prt2 assert len(prt2) assert isinstance(prt2.clear(), nt.Partition) assert len(prt2) == 0
def test_MPlug(self): persp = nt.Node("persp") front = nt.Node("front") side = nt.Node("side") matworld = persp.worldMatrix assert isinstance(matworld.mfullyQualifiedName(), basestring) str(matworld) repr(matworld) # CONNECTIONS ####################### # CHECK COMPOUND ACCESS tx = persp.translate.mchildByName('tx') # can access attributes twice persp.translate # DO CONNECTIONS ( test undo/redo ) persp.translate.mconnectTo(front.translate, force=True) assert persp.translate.misConnectedTo( front.translate) # misConnectedTo assert persp.translate.minput().isNull() cmds.undo() assert not persp.translate.misConnectedTo(front.translate) cmds.redo() assert front.translate in persp.translate.moutputs() # check moutput assert persp.translate.moutput() == front.translate assert persp.rotate.moutput().isNull( ) # unconnected return nullPlus as minput does # CHECK CONNECTION FORCING persp.translate.mconnectTo(front.translate, force=False) # already connected self.failUnlessRaises(RuntimeError, persp.s.mconnectTo, front.translate, force=False) # overwrite connection side.translate.mconnectTo(front.translate) # force default True assert side.translate.misConnectedTo(front.translate) # undo - old connection should be back cmds.undo() assert persp.translate.misConnectedTo(front.translate) # disconnect input front.translate.mdisconnectInput() assert not persp.translate.misConnectedTo(front.translate) cmds.undo() # disconnect output persp.t.mdisconnectOutputs() assert len(persp.translate.moutputs()) == 0 cmds.undo() assert persp.t.misConnectedTo(front.translate) # disconnect from persp.t.mdisconnectFrom(front.translate) assert not persp.t.misConnectedTo(front.t) cmds.undo() assert persp.t.misConnectedTo(front.t) # COMPARISONS assert persp.t != front.t assert persp.t.mchildByName('tx') != persp.t.mchildByName('ty') # affected plugs affectedPlugs = persp.t.maffects() assert len(affectedPlugs) > 1 affectedPlugs = persp.t.maffected() assert len(affectedPlugs) > 1 # test multi connections sn = nt.createNode("network1", "network") sn2 = nt.createNode("network2", "network") tn = nt.createNode("network3", "network") def pir(array_plug, range_iter): for index in range_iter: yield array_plug.elementByLogicalIndex(index) # END for each item in range # END plugs-in-range # connect 10 to 10 r = range(10) api.MPlug.mconnectMultiToMulti(izip(pir(sn.a, r), pir(tn.affectedBy, r)), force=False) for i in r: assert sn.a.elementByLogicalIndex(i).misConnectedTo( tn.affectedBy.elementByLogicalIndex(i)) # END make connection assertion # connection of overlapping range fails without force r = range(5, 15) self.failUnlessRaises(RuntimeError, api.MPlug.mconnectMultiToMulti, izip(pir(sn2.a, r), pir(tn.affectedBy, r)), force=False) # there no connection should have worked ( its atomic ) # hence slot 10 is free persp.tx > tn.affectedBy.elementByLogicalIndex(10) # force connection works api.MPlug.mconnectMultiToMulti(izip(pir(sn2.a, r), pir(tn.affectedBy, r)), force=True) for i in r: assert sn2.a.elementByLogicalIndex(i).misConnectedTo( tn.affectedBy.elementByLogicalIndex(i)) # END make connection assertion # ATTRIBUTES AND UNDO ####################### funcs = (("isLocked", "msetLocked"), ("isKeyable", "msetKeyable"), ("isCachingFlagSet", "msetCaching"), ("isChannelBoxFlagSet", "msetChannelBox")) plugnames = ("t", "tx", "r", "rx", "s", "sy") for p in plugnames: plug = persp.findPlug(p) for (getname, setname) in funcs: fget = getattr(plug, getname) fset = getattr(plug, setname) curval = fget() oval = bool(1 - curval) fset(oval) # SPECIAL HANDLING as things cannot be uncached if setname == "msetCaching": continue assert fget() == oval cmds.undo() assert fget() == curval cmds.redo() assert fget() == oval fset(curval) # reset # END for each function # END for each plugname # QUERY ############################ # ELEMENT ITERATION matworld.evaluateNumElements() for elm in matworld: assert elm.mparent() == matworld translate = persp.translate assert len(translate.mchildren()) == translate.numChildren() # CHILD ITERATION for child in translate.mchildren(): assert child.mparent() == translate assert len(translate.mchildren()) == 3 # SUB PLUGS GENERAL METHOD assert len(matworld) == len(matworld.msubPlugs()) assert translate.numChildren() == len(translate.msubPlugs()) assert len(translate.msubPlugs()) == 3 # ARRAY CONNECTIONS ################### objset = nt.createNode("set1", "objectSet") partition = nt.createNode("partition1", "partition") pma = nt.createNode("plusMinusAverage1", "plusMinusAverage") destplug = persp.translate.mconnectToArray(pma.input3D, exclusive_connection=True) assert persp.translate.misConnectedTo(destplug) # exclusive connection should return exisiting plug assert persp.translate.mconnectToArray( pma.input3D, exclusive_connection=True) == destplug # but newones can also be created assert persp.translate.mconnectToArray( pma.input3D, exclusive_connection=False) != destplug #assert objset.partition.mconnectToArray( partition.sets, exclusive_connection = False ) != destplug # assure the standin classes are there - otherwise my list there would # bind to the standins as the classes have not been created yet plugs = [matworld, translate] for plug in plugs: plug.mwrappedAttribute() # CHECK ATTRIBUTES and NODES for plug, attrtype in zip(plugs, [nt.TypedAttribute, nt.CompoundAttribute]): attr = plug.mwrappedAttribute() assert isinstance(attr, nt.Attribute) assert isinstance(attr, attrtype) node = plug.mwrappedNode() assert isinstance(node, nt.Node) assert node == persp # UNDO / REDO ############## cam = nt.createNode("myTrans", "transform") testdb = [(cam.visibility, "Bool", True, False), (cam.tx, "Double", 0.0, 2.0)] # TODO: Add all missing types ! for plug, typename, initialval, targetval in testdb: getattrfunc = getattr(plug, "as" + typename) setattrfunc = getattr(plug, "mset" + typename) assert getattrfunc() == initialval setattrfunc(targetval) assert getattrfunc() == targetval cmds.undo() assert getattrfunc() == initialval cmds.redo() assert getattrfunc() == targetval # END for each tuple in testdb # TEST EVERYTHING ################# # This part has been written to be very sure every customized method gets # called at least once. I don't trust my 'old' tests, although they do # something and are valuable to the testing framework. nwnode = nt.Network() persp.msg.mct(nwnode.affectedBy.elementByLogicalIndex(0)) front.msg.mct(nwnode.affectedBy.elementByLogicalIndex(1)) t = persp.translate tx = persp.tx wm = persp.wm a = nwnode.affectedBy a.evaluateNumElements() assert len(wm) == 1 and len(a) == 2 assert isinstance(iter(wm).next(), api.MPlug) assert len(list(a)) == 2 # test str/repr assert str(wm) != str(a) assert repr(wm) != str(wm) assert wm != a # is it really necessary to apply custom handling here ? Check __eq__ method # test comparison assert a[0] == a[0] assert a[0] != a[1] # mparent assert tx.mparent() == t assert a[0].mparent() == a # mchildren assert len(a[0].mchildren()) == 0 assert len(t.mchildren()) == 3 # mchildByName assert t.mchildByName('tx') == tx self.failUnlessRaises(TypeError, tx.mchildByName, 'something') self.failUnlessRaises(AttributeError, t.mchildByName, 'doesntexist') # msubPlugs assert len(t.msubPlugs()) == 3 assert len(a.msubPlugs()) == 2 assert len(tx.msubPlugs()) == 0 # msetLocked tx.msetLocked(1) assert tx.isLocked() tx.msetLocked(0) assert not tx.isLocked() # msetKeyable tx.msetKeyable(0) assert not tx.isKeyable() tx.msetKeyable(1) assert tx.isKeyable() # msetCaching tx.msetCaching(0) #assert not tx.isCachingFlagSet() # for some reason, the caching cannot be changed here tx.msetCaching(1) assert tx.isCachingFlagSet() == 1 # msetChannelBox tx.msetChannelBox(0) assert not tx.isChannelBoxFlagSet() tx.msetChannelBox(1) assert tx.isChannelBoxFlagSet() == 1 # mconnectMultiToMulti # is tested elsewhere # connectTo self.failUnlessRaises(RuntimeError, persp.msg.mconnectTo, a[1], force=False) # already connected front.msg.mconnectTo(a[1], force=False) # already connected front.msg.mconnectTo(a[0], force=True) # force breaks connections persp.msg.mconnectTo(a[0]) # default is force # mconnectToArray # sufficiently tested ( -> st ) # mdisconnect # st # mdisconnectInput # st # mdisconnectOutputs # st # mdisconnectFrom # st # mdisconnectNode # st # mhaveConnection assert api.MPlug.mhaveConnection( front.msg, a[1]) and api.MPlug.mhaveConnection(a[1], front.msg) assert not api.MPlug.mhaveConnection( persp.msg, a[1]) and not api.MPlug.mhaveConnection( a[1], persp.msg) # misConnectedTo # st # moutputs assert len( front.msg.moutputs()) == 1 and front.msg.moutputs()[0] == a[1] assert len(a[0].moutputs()) == 0 # moutput # st # minputs assert len(a.minputs()) == 2 assert len(a[1].minputs()) == 1 # miterGraph # st # miterInputGraph # st # miterOutputGraph # st # minput # st # mconnections assert len(front.msg.mconnections()) == 2 assert len(a[1].mconnections()) == 2 # mdependencyInfo m = nt.Mesh() assert len(m.outMesh.maffected()) assert isinstance(m.outMesh.maffected()[0], api.MPlug) assert m.outMesh.maffected() == m.outMesh.mdependencyInfo(by=True) assert isinstance(m.inMesh.maffects(), list) # no affected items for some reason assert m.inMesh.maffects() == m.inMesh.mdependencyInfo(by=False) # mnextLogicalIndex|plug assert a.mnextLogicalIndex() == 2 assert a.mnextLogicalPlug().logicalIndex() # mwrappedAttribute assert isinstance(a.mwrappedAttribute(), nt.Attribute) # mwrappedNode assert isinstance(a.mwrappedNode(), nt.Node) # masData nt.PolyCube().output.mconnectTo(m.inMesh) # need data here assert isinstance(m.outMesh.masData(), nt.Data) # mfullyQualifiedName assert a.mfullyQualifiedName() != a.partialName()
def test_partitions( self ): # one transform, two sets, one partition s1 = nt.createNode( "ms1", "objectSet" ) s2 = nt.createNode( "ms2", "objectSet" ) p = nt.createNode( "p1", "partition" ) s3 = nt.createNode( "ms3", "objectSet" ) s4 = nt.createNode( "ms4", "objectSet" ) t = nt.createNode( "my_trans", "transform" ) t2 = nt.createNode( "my_trans2", "transform" ) p.addSets( [ s1, s2 ] ) # Also adding sets ################ # Internally the check for added objects can use intersection operations # to see whether objects are actually in there - if there would not be # some notion of 'sets_are_members', it would take the members of sets as items for # intersection for o1, o2 in [ (t,t2), (s3,s4) ]: # SINGLE OBJECT ############### multiobj = [ o1, o2 ] s1.addMember( o1 ) self.failUnlessRaises( nt.ConstraintError, s2.addMember, o1 ) # failure, as errors are not ignored s2.addMember( o1, ignore_failure = 1 ) # ignore failure # FORCE s2.addMember( o1, force = 1 ) assert s2.isMember( o1 ) # MULTIPLE OBJECTS ################### self.failUnlessRaises( nt.ConstraintError, s1.addMembers, multiobj ) # fails as t is in s2 s1.addMembers( [ o2 ] ) # works as t2 is not in any set yet assert s1.isMember( o2 ) # FORCE all objects into s1 s1.addMembers( multiobj, force = 1 ) assert s1.intersection( multiobj, sets_are_members = 1 ).length() == 2 # and once more assert isinstance(s1.clear(), nt.ObjectSet) s2.clear() for s in s1,s2: assert s.members().length() == 0 s1.addMembers( multiobj ) self.failUnlessRaises( nt.ConstraintError, s2.addMembers, multiobj, force = False, ignore_failure = False ) assert s2.members().length() == 0 s2.addMembers( multiobj, force = False, ignore_failure = 1 ) assert s2.members().length() == 0 # now force it s2.addMembers( multiobj, force = 1 ) assert s2.members().length() == 2 # END for each object # SHADER ASSIGNMENTS ###################### sphere = nt.Node( cmds.polySphere( )[0] )[0] cube = nt.Node( cmds.polyCube()[0] )[0] multi = ( sphere, cube ) all_sets = sphere.connectedSets( setFilter = sphere.fSets ) isg = all_sets[0] # initial shading group rp = isg.partitions()[0]# render partition assert str( isg ).startswith( "initial" ) snode = nt.createNode( "mysg", "shadingEngine" ) snode.setPartition( rp, 1 ) self.failUnlessRaises( nt.ConstraintError, snode.addMember, sphere ) self.failUnlessRaises( nt.ConstraintError, snode.addMembers, multi ) # now force it in snode.addMembers( multi, force = 1, ignore_failure = 0 ) assert snode.members().length() == 2 assert snode.intersection( multi ).length() == 2
def test_wrapDepNode( self ): node = nt.Node( "defaultRenderGlobals" ) # SKIP CHECKS TEST self.failUnlessRaises( ValueError, nt.Node, "this" ) # does not exist # results inconsitent between maya 8.5 and 2008, thus we skip it as it is not of much value # self.failUnlessRaises( TypeError, nt.Node, "this", 1 ) # skip check , maya throws # string should be name assert str( node ) == node.name( ) repr( node ) # must not have methods that require undo try: node.create( "this" ) node.setName( "this" ) except AttributeError: pass except: raise # could fail, but raise is better # get simple attributes for attr in [ "preMel", "postMel" ]: plug = getattr( node, attr ) assert plug == getattr( node, attr ) assert plug == node.findPlug(attr) assert not plug.isNull() # check connection methods cons = node.connections( ) assert len( cons ) # DEPENDENCY INFO persp = nt.Node( "persp" ) affected_attrs = persp.dependencyInfo( "t", by=0 ) assert len( affected_attrs ) > 1 affected_attrs = persp.dependencyInfo( "t", by=1 ) assert len( affected_attrs ) > 1 assert isinstance(affected_attrs[0], nt.Attribute) # CHECK LAZY WRAPPING # get mfn lazy wrapped attributes t = node.attributeCount() for state in [1,0]: node.setLocked( state ) assert node.isLocked() == state # ATTRIBUTES attr = node.attribute( 0 ) attr.name( ) assert not attr.isNull() for i in xrange( node.attributeCount() ): attr = node.attribute( i ) assert not attr.isNull() and attr.name() # CHECK namespaces - should be root namespace ns = node.namespace( ) assert ns == nt.Namespace.rootpath # RENAME DEP NODES ###################### node = nt.createNode( "mynode", "facade" ) renamed = node.rename( "myrenamednode" ) assert renamed.name() == "myrenamednode" assert node == renamed # undo - redo cmds.undo() assert node.name() == "mynode" cmds.redo() assert node.name() == "myrenamednode" # trigger namespace error self.failUnlessRaises( RuntimeError, node.rename, "nsdoesnotexist:othername", autocreateNamespace = False ) # now it should work node.rename( "nsdoesnotexist:othername", autocreateNamespace=True ) # multi undo - namespace is one operation in this one cmds.undo() assert not nsm.existsNamespace( "nsdoesnotexist" ) cmds.redo() assert node.isValid() # rename to same name renamed = node.rename( "nsdoesnotexist" ) # should be fine assert renamed == node # othernode with different type exists othernode = nt.createNode( "othernode", "groupId" ) self.failUnlessRaises( RuntimeError, node.rename, "othernode", renameOnClash = False ) # locking othernode.setLocked( 1 ) assert othernode.isLocked() cmds.undo( ) assert not othernode.isLocked() cmds.redo() assert othernode.isLocked() othernode.setLocked( 0 ) assert not othernode.isLocked() # works if rename enabeld though node.rename( "othernode" )
def test_MPlug( self ): persp = nt.Node( "persp" ) front = nt.Node( "front" ) side = nt.Node( "side" ) matworld = persp.worldMatrix assert isinstance(matworld.mfullyQualifiedName(), basestring) str( matworld ) repr( matworld ) # CONNECTIONS ####################### # CHECK COMPOUND ACCESS tx = persp.translate.mchildByName('tx') # can access attributes twice persp.translate # DO CONNECTIONS ( test undo/redo ) persp.translate.mconnectTo(front.translate, force=True) assert persp.translate.misConnectedTo(front.translate) # misConnectedTo assert persp.translate.minput().isNull( ) cmds.undo( ) assert not persp.translate.misConnectedTo( front.translate ) cmds.redo( ) assert front.translate in persp.translate.moutputs() # check moutput assert persp.translate.moutput() == front.translate assert persp.rotate.moutput().isNull() # unconnected return nullPlus as minput does # CHECK CONNECTION FORCING persp.translate.mconnectTo(front.translate, force=False) # already connected self.failUnlessRaises( RuntimeError, persp.s.mconnectTo, front.translate, force=False ) # overwrite connection side.translate.mconnectTo(front.translate) # force default True assert side.translate.misConnectedTo(front.translate) # undo - old connection should be back cmds.undo() assert persp.translate.misConnectedTo(front.translate) # disconnect input front.translate.mdisconnectInput() assert not persp.translate.misConnectedTo(front.translate) cmds.undo() # disconnect output persp.t.mdisconnectOutputs( ) assert len( persp.translate.moutputs() ) == 0 cmds.undo() assert persp.t.misConnectedTo( front.translate ) # disconnect from persp.t.mdisconnectFrom(front.translate) assert not persp.t.misConnectedTo(front.t) cmds.undo() assert persp.t.misConnectedTo(front.t) # COMPARISONS assert persp.t != front.t assert persp.t.mchildByName('tx') != persp.t.mchildByName('ty') # affected plugs affectedPlugs = persp.t.maffects( ) assert len( affectedPlugs ) > 1 affectedPlugs = persp.t.maffected( ) assert len( affectedPlugs ) > 1 # test multi connections sn = nt.createNode("network1", "network") sn2 = nt.createNode("network2", "network") tn = nt.createNode("network3", "network") def pir(array_plug, range_iter): for index in range_iter: yield array_plug.elementByLogicalIndex(index) # END for each item in range # END plugs-in-range # connect 10 to 10 r = range(10) api.MPlug.mconnectMultiToMulti( izip(pir(sn.a, r), pir(tn.affectedBy, r)), force=False) for i in r: assert sn.a.elementByLogicalIndex(i).misConnectedTo(tn.affectedBy.elementByLogicalIndex(i)) # END make connection assertion # connection of overlapping range fails without force r = range(5, 15) self.failUnlessRaises(RuntimeError, api.MPlug.mconnectMultiToMulti, izip(pir(sn2.a, r), pir(tn.affectedBy, r)), force=False) # there no connection should have worked ( its atomic ) # hence slot 10 is free persp.tx > tn.affectedBy.elementByLogicalIndex(10) # force connection works api.MPlug.mconnectMultiToMulti(izip(pir(sn2.a, r), pir(tn.affectedBy, r)), force=True) for i in r: assert sn2.a.elementByLogicalIndex(i).misConnectedTo(tn.affectedBy.elementByLogicalIndex(i)) # END make connection assertion # ATTRIBUTES AND UNDO ####################### funcs = ( ( "isLocked", "msetLocked" ), ( "isKeyable", "msetKeyable" ), ( "isCachingFlagSet", "msetCaching" ), ( "isChannelBoxFlagSet", "msetChannelBox" ) ) plugnames =( "t", "tx", "r","rx", "s", "sy" ) for p in plugnames: plug = persp.findPlug(p) for ( getname, setname ) in funcs: fget = getattr( plug, getname ) fset = getattr( plug, setname ) curval = fget() oval = bool( 1 - curval ) fset( oval ) # SPECIAL HANDLING as things cannot be uncached if setname == "msetCaching": continue assert fget() == oval cmds.undo() assert fget() == curval cmds.redo() assert fget() == oval fset( curval ) # reset # END for each function # END for each plugname # QUERY ############################ # ELEMENT ITERATION matworld.evaluateNumElements( ) for elm in matworld: assert elm.mparent( ) == matworld translate = persp.translate assert len( translate.mchildren() ) == translate.numChildren() # CHILD ITERATION for child in translate.mchildren( ): assert child.mparent( ) == translate assert len( translate.mchildren() ) == 3 # SUB PLUGS GENERAL METHOD assert len( matworld ) == len( matworld.msubPlugs() ) assert translate.numChildren() == len( translate.msubPlugs() ) assert len( translate.msubPlugs() ) == 3 # ARRAY CONNECTIONS ################### objset = nt.createNode( "set1", "objectSet" ) partition = nt.createNode( "partition1", "partition" ) pma = nt.createNode( "plusMinusAverage1", "plusMinusAverage" ) destplug = persp.translate.mconnectToArray( pma.input3D, exclusive_connection = True ) assert persp.translate.misConnectedTo(destplug) # exclusive connection should return exisiting plug assert persp.translate.mconnectToArray( pma.input3D, exclusive_connection = True ) == destplug # but newones can also be created assert persp.translate.mconnectToArray( pma.input3D, exclusive_connection = False ) != destplug #assert objset.partition.mconnectToArray( partition.sets, exclusive_connection = False ) != destplug # assure the standin classes are there - otherwise my list there would # bind to the standins as the classes have not been created yet plugs = [ matworld, translate ] for plug in plugs: plug.mwrappedAttribute() # CHECK ATTRIBUTES and NODES for plug, attrtype in zip( plugs, [ nt.TypedAttribute, nt.CompoundAttribute ] ): attr = plug.mwrappedAttribute( ) assert isinstance( attr, nt.Attribute ) assert isinstance( attr, attrtype ) node = plug.mwrappedNode() assert isinstance( node, nt.Node ) assert node == persp # UNDO / REDO ############## cam = nt.createNode( "myTrans", "transform" ) testdb = [ ( cam.visibility, "Bool", True, False ), ( cam.tx, "Double", 0.0, 2.0 ) ] # TODO: Add all missing types ! for plug, typename, initialval, targetval in testdb: getattrfunc = getattr( plug, "as"+typename ) setattrfunc = getattr( plug, "mset"+typename ) assert getattrfunc() == initialval setattrfunc( targetval ) assert getattrfunc() == targetval cmds.undo() assert getattrfunc() == initialval cmds.redo() assert getattrfunc() == targetval # END for each tuple in testdb # TEST EVERYTHING ################# # This part has been written to be very sure every customized method gets # called at least once. I don't trust my 'old' tests, although they do # something and are valuable to the testing framework. nwnode = nt.Network() persp.msg.mct(nwnode.affectedBy.elementByLogicalIndex(0)) front.msg.mct(nwnode.affectedBy.elementByLogicalIndex(1)) t = persp.translate tx = persp.tx wm = persp.wm a = nwnode.affectedBy a.evaluateNumElements() assert len(wm) == 1 and len(a) == 2 assert isinstance(iter(wm).next(), api.MPlug) assert len(list(a)) == 2 # test str/repr assert str(wm) != str(a) assert repr(wm) != str(wm) assert wm != a # is it really necessary to apply custom handling here ? Check __eq__ method # test comparison assert a[0] == a[0] assert a[0] != a[1] # mparent assert tx.mparent() == t assert a[0].mparent() == a # mchildren assert len(a[0].mchildren()) == 0 assert len(t.mchildren()) == 3 # mchildByName assert t.mchildByName('tx') == tx self.failUnlessRaises(TypeError, tx.mchildByName, 'something') self.failUnlessRaises(AttributeError, t.mchildByName, 'doesntexist') # msubPlugs assert len(t.msubPlugs()) == 3 assert len(a.msubPlugs()) == 2 assert len(tx.msubPlugs()) == 0 # msetLocked tx.msetLocked(1) assert tx.isLocked() tx.msetLocked(0) assert not tx.isLocked() # msetKeyable tx.msetKeyable(0) assert not tx.isKeyable() tx.msetKeyable(1) assert tx.isKeyable() # msetCaching tx.msetCaching(0) #assert not tx.isCachingFlagSet() # for some reason, the caching cannot be changed here tx.msetCaching(1) assert tx.isCachingFlagSet() == 1 # msetChannelBox tx.msetChannelBox(0) assert not tx.isChannelBoxFlagSet() tx.msetChannelBox(1) assert tx.isChannelBoxFlagSet() == 1 # mconnectMultiToMulti # is tested elsewhere # connectTo self.failUnlessRaises(RuntimeError, persp.msg.mconnectTo, a[1], force=False) # already connected front.msg.mconnectTo(a[1], force=False) # already connected front.msg.mconnectTo(a[0], force=True) # force breaks connections persp.msg.mconnectTo(a[0]) # default is force # mconnectToArray # sufficiently tested ( -> st ) # mdisconnect # st # mdisconnectInput # st # mdisconnectOutputs # st # mdisconnectFrom # st # mdisconnectNode # st # mhaveConnection assert api.MPlug.mhaveConnection(front.msg, a[1]) and api.MPlug.mhaveConnection(a[1], front.msg) assert not api.MPlug.mhaveConnection(persp.msg, a[1]) and not api.MPlug.mhaveConnection(a[1], persp.msg) # misConnectedTo # st # moutputs assert len(front.msg.moutputs()) == 1 and front.msg.moutputs()[0] == a[1] assert len(a[0].moutputs()) == 0 # moutput # st # minputs assert len(a.minputs()) == 2 assert len(a[1].minputs()) == 1 # miterGraph # st # miterInputGraph # st # miterOutputGraph # st # minput # st # mconnections assert len(front.msg.mconnections()) == 2 assert len(a[1].mconnections()) == 2 # mdependencyInfo m = nt.Mesh() assert len(m.outMesh.maffected()) assert isinstance(m.outMesh.maffected()[0], api.MPlug) assert m.outMesh.maffected() == m.outMesh.mdependencyInfo(by=True) assert isinstance(m.inMesh.maffects(), list) # no affected items for some reason assert m.inMesh.maffects() == m.inMesh.mdependencyInfo(by=False) # mnextLogicalIndex|plug assert a.mnextLogicalIndex() == 2 assert a.mnextLogicalPlug().logicalIndex() # mwrappedAttribute assert isinstance(a.mwrappedAttribute(), nt.Attribute) # mwrappedNode assert isinstance(a.mwrappedNode(), nt.Node) # masData nt.PolyCube().output.mconnectTo(m.inMesh) # need data here assert isinstance(m.outMesh.masData(), nt.Data) # mfullyQualifiedName assert a.mfullyQualifiedName() != a.partialName()
def test_childEditing( self ): base = nt.createNode( "basenode", "transform" ) obase = nt.createNode( "otherbasenode", "transform" ) trans = nt.createNode( "trans", "transform" ) otrans = nt.createNode( "parent|trans", "transform" ) mesh = nt.createNode( "meshparent|meshshape", "mesh" ) curve = nt.createNode( "nurbsparent|ncurve", "nurbsCurve" ) itemlist = [ trans, mesh, curve ] instlist = [] # MULTIPLE ADDS #################### # Returns the same instance - its what the user wants for item in itemlist: baseiteminst = base.addInstancedChild( item ) base.addInstancedChild( item ) assert item != baseiteminst and baseiteminst.isValid() and item.isValid() instlist.append( baseiteminst ) # UNDO TEST # undo basemesh cmds.undo() cmds.undo() assert not baseiteminst.isValid() and baseiteminst.isAlive() cmds.redo() assert baseiteminst.isValid() and baseiteminst.isAlive() # END for each object including undo/redo # KEEP PARENT FALSE - USE INSTANCES # TODO: this test needs a redo - the original purpose got lost when # the addChild method has been changed, additionally it needs to be # better documented as this instancing stuff is not easily understood if # one just sees the code for orig,inst in zip( itemlist, instlist ): inst = obase.addChild( inst, keepExistingParent=False ) obase.addChild( inst, keepExistingParent=False ) # duplicate adds are not problem assert inst.isValid() and inst.isAlive() assert orig.isValid() # original may not be influenced by that operation # undo / redo cmds.undo() #cmds.undo() # just one undo counts assert inst.isValid() and orig.isValid() cmds.redo() # END for each instance # RENAME ON CLASH = False self.failUnlessRaises( RuntimeError, obase.addChild, otrans, renameOnClash = False ) # RENAME ON CLASH = True otransname = str( otrans ) renamedtrans = obase.addChild( otrans, renameOnClash = True ) assert renamedtrans.isValid() renamedname = str( renamedtrans ) assert renamedname != otransname cmds.undo( ) assert nt.objExists( otransname ) and not nt.objExists( renamedname ) cmds.redo()