Example #1
0
 def create(cls):
     """Create a new Network node with storage node capabilities"""
     n = nt.Network()
     n.addAttribute(
         persistence.createStorageAttribute(
             persistence.PyPickleData.kPluginDataId))
     return StorageNetworkNode(n.object())
Example #2
0
    def test_replace_non_leaf_node_types(self):
        # keep the previous type as we want to restore it
        OldDependNode = nt.DependNode

        nold = nt.Network()
        assert str(nold).startswith("network")

        # overwriting the foundation of all nodes will not change anything
        # for existing node types, as they have bound the previous type already.
        class DependNode(nt.Node):
            """This type cannot do anything, we have removed functionality"""
            def __str__(self):
                return 'me_as_string'

        # END custom DependNode

        assert str(nold).startswith('network')

        # new instances still use the default implementation
        nnew = nt.Network()
        assert str(nnew).startswith('network')

        # also we cannot instatiate it explicitly as we are not inheriting
        # from the type that MRV wants to create, Network
        self.failUnlessRaises(TypeError, DependNode, nnew.object())

        # we could get away with this, but we clean it up anyway
        nt.removeCustomType(DependNode)
        nt.addCustomType(OldDependNode)

        # MONKEY PATCHING
        #################
        # The only way to get custom method implementation directly into the non-leaf
        # node types is monkey patching, hence existing methods will be overwritten
        # with your implementation
        # Using the dict for retrieval as one would get class methods otherwise, these
        # check for the actual type passed in which would fail in our case.
        old_str = nt.DependNode.__dict__['__str__']
        nt.DependNode.__str__ = DependNode.__dict__['__str__']

        assert str(nold) == 'me_as_string'
        # undo our changes
        nt.DependNode.__str__ = old_str
Example #3
0
	def test_namespace_adjustment(self):
		dag = nt.Transform()
		dg = nt.Network()
		
		childns = nsm.Namespace.create(":foo:bar")
		parentns = childns.parent()
		for node in (dag, dg):
			assert node.namespace() == nsm.RootNamespace
			assert isinstance(node.setNamespace(childns), nt.Node)
			
			assert node.namespace() == childns
			assert node.setNamespace(parentns).namespace() == parentns
			assert node.setNamespace(nsm.RootNamespace).namespace() == nsm.RootNamespace
Example #4
0
    def test_virtual_subtype(self):
        n = nt.Network()

        # types must define the __mrv_virtual_subtype__ attribute
        self.failUnlessRaises(TypeError, StorageNetworkNodeWrong, n.object())

        # make a StorageNetwork node
        sn = StorageNetworkNode.create()
        assert isinstance(sn, StorageNetworkNode)

        # it cannot wrap ordinary network nodes - we implemented it that way
        self.failUnlessRaises(TypeError, StorageNetworkNode, n.object())

        # iteration works fine as well
        sns = list(StorageNetworkNode.iter_instances())
        assert len(sns) == 1 and isinstance(sns[0], StorageNetworkNode)
        assert sns[0] == sn

        # be sure we can use the storage interface
        assert isinstance(sn.dataIDs(), list)
Example #5
0
    def test_replacing_default_node_types(self):
        n = nt.Network()
        sn = StorageNetworkNode.create()

        # REPLACING BUILTIN NODE TYPES
        ##############################
        # if we want to play crazy, we can make all network nodes our special
        # storage node, be replacing the existing Network node type.
        # Any instantiation will fail as if its not one of our specialized nodes,
        # but this is implementation defined of course.
        # Defining a new derived Type automatically puts it into the nt module
        OldNetwork = nt.Network

        class Network(StorageNetworkNode):
            def sayhello(self):
                print "hello"

        # yes, the official Network node is now our own one, automatically
        assert nt.Network is Network

        sn2 = nt.Node(str(sn))
        assert isinstance(sn2, StorageNetworkNode)
        assert isinstance(sn2.dataIDs(), list)

        # and it can say something
        sn2.sayhello()

        # we cannot wrap normal nodes as our initializer on StorageNetworkNode barks
        # if the vital data plug cannot be found.
        self.failUnlessRaises(TypeError, nt.Node, str(n))

        # reset the old one, we affect everything within MRV now
        nt.removeCustomType(Network)
        nt.addCustomType(OldNetwork)

        # everything back to normal - we get plain old network nodes
        sn_network = nt.Node(sn.object())
        assert type(sn_network) is OldNetwork
        assert type(sn_network) is nt.Network

        # REPLACING BUILTIN NODES PROPERLY
        ##################################
        class Network(OldNetwork, nt.StorageBase):
            def __init__(self, node):
                """Implement the initializer such that we only initialize our base
				if we have the 'data' attribute. Otherwise we keep it uninitialized, so it 
				will not be functional"""
                try:
                    super(Network, self).__init__(node)
                except TypeError:
                    pass
                # END handle input type

            def sayaloha(self):
                print "aloha"

        # END better Super-Network implementation
        assert nt.Network is Network

        # now plain network nodes will be new Network nodes, but we are allowed
        # to create them
        # NodeFromObj works as well, just to be sure
        n2 = nt.NodeFromObj(n.object())
        assert type(n2) is Network

        # as the storage base has not been initialized, we cannot do anything
        # with it. The actual point here though is that users who don't know the
        # interface will get a fully functional network node at least.
        # As we do not 'tighten' the interface, code that doesn't expect our type
        # will not get into trouble.
        self.failUnlessRaises(AttributeError, n2.dataIDs)
        assert isinstance(n2, OldNetwork)
        n2.sayaloha()

        # and storage network nodes will be 'Network' nodes whose additional
        # functions we can use
        sn2 = nt.Node(sn.object())
        assert type(sn2) is Network
        sn2.sayaloha()
        sn2.dataIDs()

        # once again, get rid of our custom type, reset the old one
        nt.removeCustomType(Network)
        nt.addCustomType(OldNetwork)
        assert nt.Network is OldNetwork
Example #6
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()