def to_file( self, output_file, **kwargs ): """export the AnimationHandle and all managed nodes to the given file :return: path to exported file :param output_file: Path object or path string to export file. Parent directories will be created as needed :param kwargs: passed to the ``Scene.export`` method""" # build selectionlist for export exp_slist = nt.toSelectionList(self.iter_animation(asNode=0)) exp_slist.add(self.object()) return Scene.export(output_file, exp_slist, **kwargs )
def test_anim_handle(self): # manage all anim nt ah = AnimationHandle.create() ahapi = ah.object() st = time.time() is_not_ah = lambda n: n != ahapi sellist = nt.toSelectionList(nt.it.iterDgNodes(asNode=False, predicate=is_not_ah)) ah.set_animation(sellist) elapsed = time.time() - st print >>sys.stderr, "Managed animation of roughly 21k nodes in %f s" % elapsed # apply animation, worst case ( as it is already connected ) st = time.time() ah.apply_animation() elapsed = time.time() - st print >>sys.stderr, "Re-Applied animation onto same existing animation of roughly 21k nodes in %f s" % elapsed # clear animation st = time.time() pa = nt.api.MPlugArray() apianim.MAnimUtil.findAnimatedPlugs(sellist, pa) # do it the fast way - its easier to use mrv, but much faster to do it # directly mod = nt.api.MDGModifier( ) for anim_plug in pa: mod.disconnect(anim_plug.minput(), anim_plug ) # END for each anim curve to disconnect mod.doIt() elapsed = time.time() - st print >>sys.stderr, "Cleared animation on %i plugs in %f s" % (len(pa), elapsed) assert len(nt.AnimCurve.findAnimation(sellist)) == 0 # apply animation, best case as it is not yet connected st = time.time() ah.apply_animation() elapsed = time.time() - st print >>sys.stderr, "Applied animation of roughly 21k nodes in %f s" % elapsed
def test_convenienceFunctions( self ): # SELECTION ############ nt.select( "persp" ) persp = nt.selection()[0] assert persp == nt.Node( "persp" ) # clear selection nt.select( ) assert not nt.selection() # undo/redo cmds.undo() assert len(nt.selection()) == 1 cmds.redo() assert len(nt.selection()) == 0 # select object and selection list nt.select( persp ) assert len( nt.selection( ) ) == 1 nt.select( nt.toSelectionList( nt.selection( ) ) ) assert len( nt.selection( ) ) == 1 # select mixed nt.select( persp, "front" ) assert len( nt.selection( ) ) == 2 # GET BY NAME ############### persp = nt.findByName( "pers*" )[0] assert persp == nt.Node( "persp" ) # filter selection ################## nt.select("persp", "perspShape") assert len(nt.selection(api.MFn.kCamera)) == 1 assert len(list(nt.iterSelection(api.MFn.kCamera))) == 1 sl = nt.activeSelectionList() assert len(sl) and isinstance(sl, api.MSelectionList)
def test_convenienceFunctions(self): # SELECTION ############ nt.select("persp") persp = nt.selection()[0] assert persp == nt.Node("persp") # clear selection nt.select() assert not nt.selection() # undo/redo cmds.undo() assert len(nt.selection()) == 1 cmds.redo() assert len(nt.selection()) == 0 # select object and selection list nt.select(persp) assert len(nt.selection()) == 1 nt.select(nt.toSelectionList(nt.selection())) assert len(nt.selection()) == 1 # select mixed nt.select(persp, "front") assert len(nt.selection()) == 2 # GET BY NAME ############### persp = nt.findByName("pers*")[0] assert persp == nt.Node("persp") # filter selection ################## nt.select("persp", "perspShape") assert len(nt.selection(api.MFn.kCamera)) == 1 assert len(list(nt.iterSelection(api.MFn.kCamera))) == 1 sl = nt.activeSelectionList() assert len(sl) and isinstance(sl, api.MSelectionList)
def test_get_animation( self ): mmaya.Scene.new(force=True) p = nt.Node("persp") # translate is animated for tc in p.translate.mchildren(): apianim.MFnAnimCurve().create(tc) # END set animation # test animation iteration for converter in (lambda x: x, lambda x: nt.toSelectionList(x)): for as_node in range(2): nc = 0 target_type = nt.api.MObject if as_node: target_type = nt.Node # END define target type for anode in nt.AnimCurve.findAnimation(converter([p]), as_node): assert isinstance(anode, target_type) nc += 1 # END for each anim node assert nc == 3
def test_get_animation(self): mmaya.Scene.new(force=True) p = nt.Node("persp") # translate is animated for tc in p.translate.mchildren(): apianim.MFnAnimCurve().create(tc) # END set animation # test animation iteration for converter in (lambda x: x, lambda x: nt.toSelectionList(x)): for as_node in range(2): nc = 0 target_type = nt.api.MObject if as_node: target_type = nt.Node # END define target type for anode in nt.AnimCurve.findAnimation( converter([p]), as_node): assert isinstance(anode, target_type) nc += 1 # END for each anim node assert nc == 3
def test_MSelectionList( self ): sl = nt.toSelectionList(nt.it.iterDgNodes()) nodeset = set() # can be handled like a list assert len(sl) > 3 # provides unique wrapped nodes for node in sl.mtoIter(): assert isinstance(node, nt.Node) nodeset.add(node) # END for each node assert len(nodeset) == len(sl) # test creation functions node_list = list(sl.mtoIter()) nls = node_list[4:15] for slsnodesgen, selfun in ((lambda : [str(n) for n in nls], api.MSelectionList.mfromStrings), (lambda : nls, api.MSelectionList.mfromList), (lambda : [(n, api.MObject()) for n in node_list[-5:] if isinstance(n, nt.DagNode)], api.MSelectionList.mfromComponentList) ): slsnodes = slsnodesgen() sls = selfun(iter(slsnodes)) assert isinstance(sls, api.MSelectionList) and len(sls) == len(slsnodes) # END for each variant # from multiple assert len(api.MSelectionList.mfromMultiple(*nls)) == len(nls) # from iter assert len(api.MSelectionList.mfromIter(iter(nls))) == len(nls) # test conversion methods assert list(sl.mtoIter()) == sl.mtoList() assert hasattr(sl.mtoIter(), 'next') # test contains dagnode = nt.Node("persp") dgnode = nt.Node("time1") plug = dgnode.o sls = api.MSelectionList.mfromList((dagnode, dgnode, plug)) assert len(sls) == 3 nc = 0 for item in sls.mtoIter(): assert sls.mhasItem(item) nc += 1 # END for each item assert nc == len(sls) # COMPONENT ITERATION m = nt.Mesh() nt.PolyCube().output > m.inMesh sl = api.MSelectionList() sl.add(m.dagPath()) sl.add(m.dagPath(), m.cf[:]) assert len(list(sl.miterComponents())) == 1 # PLUG ITERATION p = nt.Node("persp") sl = api.MSelectionList() sl.add(p.dagPath()) sl.add(p.t) sl.add(p.rx) assert len(list(sl.miterPlugs())) == 2
def test_export_import( self ): def iter_dag(): return nt.iterDgNodes(nt.api.MFn.kDagNode, asNode=0) ah = AnimationHandle.create() ah.set_animation(iter_dag()) # test iter_animation managed = len(list(ah.iter_animation(asNode=0))) assert managed == len(ah.affectedBy) # test iter_animtion return types assert isinstance(ah.iter_animation().next(), nt.Node) assert isinstance(ah.iter_animation(asNode=0).next(), nt.api.MObject) # selection is maintained across exports slist = nt.toSelectionList(iter_dag()) nt.select(slist) ## EXPORT ## filename = ospath.join(tempfile.gettempdir(), "test_export2.ani.ma") assert filename == ah.to_file(filename, force=True, type="mayaAscii") # check if testselection is still alive assert len(slist)==len(nt.activeSelectionList()) # AnimationHandle deletes correctly when not referenced ahname = ah.name() ah.delete() assert not ah.isValid() ## IMPORT ## # try different namespaces - it should work no matter which namespace # is current namespaces=(":", "not:in:rootns", "not") # dummyAnimationHandle for iteration tests dummy=AnimationHandle() for namespace in namespaces: sns = Namespace.create(namespace) sns.setCurrent() # check return values of from_file and get AnimationHandle ahref, ahit = AnimationHandle.from_file(filename) assert isinstance(ahref, FileReference) loaded_ah = ahit.next() assert isinstance(loaded_ah, AnimationHandle) # expecting only one AnimationHandle from iterator (no dummyAnimationHandle) # which is in our scene already assert len(list(ahit)) == 0 # check if AnimationHandle is the one we saved before loaded_ah_ns = loaded_ah.namespace() assert loaded_ah_ns + ahname == Namespace.rootpath + loaded_ah.name() # check if AnimationHandle is from file we wanted assert ospath.realpath(filename) == ospath.realpath(loaded_ah.referenceFile()) # stored and loaded managed animCurves are in sync assert managed == len(loaded_ah.affectedBy) # AnimationHandle deletes correctly when referenced loaded_ah.delete() assert not loaded_ah.isValid() # END test different namespaces os.remove(filename)
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_iter_animation(self): # get all nodes, get all animation from them for as_node in range(2): # find animation st = time.time() sel_list = nt.toSelectionList(nt.it.iterDgNodes(asNode=False)) anim_nodes = nt.AnimCurve.findAnimation(sel_list, as_node) num_nodes = len(anim_nodes) elapsed = time.time() - st print >>sys.stderr, "Found %i animation nodes ( as_node=%i ) in %f s ( %f anim nodes / s )" % (num_nodes, as_node, elapsed, num_nodes/elapsed) # find animation by iteration st = time.time() iterated_anim_nodes = list(nt.it.iterDgNodes(nt.Node.Type.kAnimCurve, asNode=as_node)) elapsed = time.time() - st print >>sys.stderr, "Iterated %i animation nodes ( as_node=%i ) in %f s ( %f anim nodes / s )" % (len(iterated_anim_nodes), as_node, elapsed, len(iterated_anim_nodes)/elapsed) # check plug access if as_node: st = time.time() for anode in anim_nodes: anode.output # END for each node elapsed = time.time() - st print >>sys.stderr, "Accessed output plug on %i nodes using node.output in %f s ( %f plugs nodes / s )" % (num_nodes, elapsed, num_nodes/elapsed) st = time.time() for anode in anim_nodes: anode.findPlug('output') # END for each node elapsed_findplug = time.time() - st print >>sys.stderr, "Accessed output plug on %i nodes using node.findPlug('output') in %f s ( %f plugs nodes / s )" % (num_nodes, elapsed_findplug, num_nodes/elapsed_findplug) print >>sys.stderr, "node.findPlug is %f times as fast as node.plug" % (elapsed/elapsed_findplug) else: st = time.time() mfndep = nt.api.MFnDependencyNode() for apianode in anim_nodes: mfndep.setObject(apianode) mfndep.findPlug('output') # END for each node elapsed = time.time() - st print >>sys.stderr, "Accessed output plug on %i api nodes using mfndep.findPlug in %f s ( %f plug nodes / s )" % (num_nodes, elapsed, num_nodes/elapsed) # END attr access testing # make selection list st = time.time() anim_sel_list = nt.toSelectionList(anim_nodes) elapsed = time.time() - st print >>sys.stderr, "Convenient Selection List Creation: %f s" % elapsed # make selection list manually st = time.time() anim_sel_list = nt.api.MSelectionList() if as_node: for an in anim_nodes: anim_sel_list.add(an.apiObject()) # END for each animation node else: for apian in anim_nodes: anim_sel_list.add(apian) # END for each animation node # END handle as_node elapsed = time.time() - st print >>sys.stderr, "Optimized Selection List Creation: %f s" % elapsed st = time.time() nt.api.MGlobal.setActiveSelectionList(anim_sel_list) elapsed = time.time() - st print >>sys.stderr, "Setting Selection List as Maya-Selection: %f s" % elapsed # END for each as_node value # compare to plain mel melcmd = """select( ls("-typ", "animCurve", (listConnections ("-s", 1, "-d", 0, "-scn", 1, "-t", "animCurve", ls()))) )""" st = time.time() nt.api.MGlobal.executeCommand(melcmd, False, False) elapsed = time.time() - st print >>sys.stderr, "MEL: Get animation of all nodes and select the animcurves: %f s" % elapsed
def test_MSelectionList(self): sl = nt.toSelectionList(nt.it.iterDgNodes()) nodeset = set() # can be handled like a list assert len(sl) > 3 # provides unique wrapped nodes for node in sl.mtoIter(): assert isinstance(node, nt.Node) nodeset.add(node) # END for each node assert len(nodeset) == len(sl) # test creation functions node_list = list(sl.mtoIter()) nls = node_list[4:15] for slsnodesgen, selfun in ((lambda: [str(n) for n in nls], api.MSelectionList.mfromStrings), (lambda: nls, api.MSelectionList.mfromList), (lambda: [(n, api.MObject()) for n in node_list[-5:] if isinstance(n, nt.DagNode)], api.MSelectionList.mfromComponentList)): slsnodes = slsnodesgen() sls = selfun(iter(slsnodes)) assert isinstance(sls, api.MSelectionList) and len(sls) == len(slsnodes) # END for each variant # from multiple assert len(api.MSelectionList.mfromMultiple(*nls)) == len(nls) # from iter assert len(api.MSelectionList.mfromIter(iter(nls))) == len(nls) # test conversion methods assert list(sl.mtoIter()) == sl.mtoList() assert hasattr(sl.mtoIter(), 'next') # test contains dagnode = nt.Node("persp") dgnode = nt.Node("time1") plug = dgnode.o sls = api.MSelectionList.mfromList((dagnode, dgnode, plug)) assert len(sls) == 3 nc = 0 for item in sls.mtoIter(): assert sls.mhasItem(item) nc += 1 # END for each item assert nc == len(sls) # COMPONENT ITERATION m = nt.Mesh() nt.PolyCube().output > m.inMesh sl = api.MSelectionList() sl.add(m.dagPath()) sl.add(m.dagPath(), m.cf[:]) assert len(list(sl.miterComponents())) == 1 # PLUG ITERATION p = nt.Node("persp") sl = api.MSelectionList() sl.add(p.dagPath()) sl.add(p.t) sl.add(p.rx) assert len(list(sl.miterPlugs())) == 2
def test_iter_animation(self): # get all nodes, get all animation from them for as_node in range(2): # find animation st = time.time() sel_list = nt.toSelectionList(nt.it.iterDgNodes(asNode=False)) anim_nodes = nt.AnimCurve.findAnimation(sel_list, as_node) num_nodes = len(anim_nodes) elapsed = time.time() - st print >> sys.stderr, "Found %i animation nodes ( as_node=%i ) in %f s ( %f anim nodes / s )" % ( num_nodes, as_node, elapsed, num_nodes / elapsed) # find animation by iteration st = time.time() iterated_anim_nodes = list( nt.it.iterDgNodes(nt.Node.Type.kAnimCurve, asNode=as_node)) elapsed = time.time() - st print >> sys.stderr, "Iterated %i animation nodes ( as_node=%i ) in %f s ( %f anim nodes / s )" % ( len(iterated_anim_nodes), as_node, elapsed, len(iterated_anim_nodes) / elapsed) # check plug access if as_node: st = time.time() for anode in anim_nodes: anode.output # END for each node elapsed = time.time() - st print >> sys.stderr, "Accessed output plug on %i nodes using node.output in %f s ( %f plugs nodes / s )" % ( num_nodes, elapsed, num_nodes / elapsed) st = time.time() for anode in anim_nodes: anode.findPlug('output') # END for each node elapsed_findplug = time.time() - st print >> sys.stderr, "Accessed output plug on %i nodes using node.findPlug('output') in %f s ( %f plugs nodes / s )" % ( num_nodes, elapsed_findplug, num_nodes / elapsed_findplug) print >> sys.stderr, "node.findPlug is %f times as fast as node.plug" % ( elapsed / elapsed_findplug) else: st = time.time() mfndep = nt.api.MFnDependencyNode() for apianode in anim_nodes: mfndep.setObject(apianode) mfndep.findPlug('output') # END for each node elapsed = time.time() - st print >> sys.stderr, "Accessed output plug on %i api nodes using mfndep.findPlug in %f s ( %f plug nodes / s )" % ( num_nodes, elapsed, num_nodes / elapsed) # END attr access testing # make selection list st = time.time() anim_sel_list = nt.toSelectionList(anim_nodes) elapsed = time.time() - st print >> sys.stderr, "Convenient Selection List Creation: %f s" % elapsed # make selection list manually st = time.time() anim_sel_list = nt.api.MSelectionList() if as_node: for an in anim_nodes: anim_sel_list.add(an.apiObject()) # END for each animation node else: for apian in anim_nodes: anim_sel_list.add(apian) # END for each animation node # END handle as_node elapsed = time.time() - st print >> sys.stderr, "Optimized Selection List Creation: %f s" % elapsed st = time.time() nt.api.MGlobal.setActiveSelectionList(anim_sel_list) elapsed = time.time() - st print >> sys.stderr, "Setting Selection List as Maya-Selection: %f s" % elapsed # END for each as_node value # compare to plain mel melcmd = """select( ls("-typ", "animCurve", (listConnections ("-s", 1, "-d", 0, "-scn", 1, "-t", "animCurve", ls()))) )""" st = time.time() nt.api.MGlobal.executeCommand(melcmd, False, False) elapsed = time.time() - st print >> sys.stderr, "MEL: Get animation of all nodes and select the animcurves: %f s" % elapsed
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