Beispiel #1
0
	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 ) 
Beispiel #2
0
	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
Beispiel #3
0
	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)
Beispiel #4
0
    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)
Beispiel #5
0
 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
Beispiel #6
0
    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
Beispiel #7
0
	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
Beispiel #8
0
	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)
Beispiel #9
0
	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
Beispiel #10
0
	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
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #13
0
    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