def testSetNodePosition(self): s = Gaffer.ScriptNode() s["n"] = Gaffer.Node() g = GafferUI.GraphGadget(s) self.assertFalse(g.hasNodePosition(s["n"])) g.setNodePosition(s["n"], IECore.V2f(-100, 2000)) self.assertEqual(g.getNodePosition(s["n"]), IECore.V2f(-100, 2000)) self.assertTrue(g.hasNodePosition(s["n"]))
def testEnabledException(self): s = Gaffer.ScriptNode() s["n"] = GafferTest.AddNode() s["e"] = Gaffer.Expression() s["e"].setExpression("parent['n']['enabled'] = undefinedVariable") g = GafferUI.GraphGadget(s) self.assertTrue(g.nodeGadget(s["n"]) is not None)
def testConnectSwitch(self): s = Gaffer.ScriptNode() s["n"] = GafferTest.AddNode() s["s"] = Gaffer.SwitchComputeNode() g = GafferUI.GraphGadget(s) g.getLayout().connectNode(g, s["s"], Gaffer.StandardSet([s["n"]])) self.assertTrue(isinstance(s["s"]["in"][0], Gaffer.IntPlug)) self.assertTrue(s["s"]["in"][0].getInput().isSame(s["n"]["sum"]))
def testUnconnectedNodes(self): s = Gaffer.ScriptNode() s["one"] = LayoutNode() s["two"] = LayoutNode() g = GafferUI.GraphGadget(s) g.getLayout().layoutNodes(g) self.assertNoOverlaps(g)
def testConnectionsForNestedPlugs( self ) : script = Gaffer.ScriptNode() script["n"] = NestedPlugTestNode() script["n"]["c"] = Gaffer.Plug() script["n"]["c"]["i"] = Gaffer.IntPlug() script["n2"] = NestedPlugTestNode() script["n2"]["c"] = Gaffer.Plug( direction = Gaffer.Plug.Direction.Out ) script["n2"]["c"]["o"] = Gaffer.IntPlug( direction = Gaffer.Plug.Direction.Out ) script["n"]["c"]["i"].setInput( script["n2"]["c"]["o"] ) s = Gaffer.StandardSet( script.children() ) g = GafferUI.GraphGadget( script, s ) c = g.connectionGadget( script["n"]["c"]["i"] ) self.failUnless( c ) self.failUnless( c.srcNodule().plug().isSame( script["n2"]["c"]["o"] ) ) self.failUnless( c.dstNodule().plug().isSame( script["n"]["c"]["i"] ) ) s.remove( script["n2"] ) self.failUnless( g.nodeGadget( script["n2"] ) is None ) c = g.connectionGadget( script["n"]["c"]["i"] ) self.failUnless( c ) self.failUnless( c.srcNodule() is None ) self.failUnless( c.dstNodule().plug().isSame( script["n"]["c"]["i"] ) ) s.add( script["n2"] ) self.failUnless( g.nodeGadget( script["n2"] ) ) c = g.connectionGadget( script["n"]["c"]["i"] ) self.failUnless( c ) self.failUnless( c.srcNodule().plug().isSame( script["n2"]["c"]["o"] ) ) self.failUnless( c.dstNodule().plug().isSame( script["n"]["c"]["i"] ) ) s.remove( script["n"] ) self.failUnless( g.nodeGadget( script["n"] ) is None ) self.failUnless( g.connectionGadget( script["n"]["c"]["i"] ) is None ) s.add( script["n"] ) self.failUnless( g.nodeGadget( script["n"] ) ) c = g.connectionGadget( script["n"]["c"]["i"] ) self.failUnless( c ) self.failUnless( c.srcNodule().plug().isSame( script["n2"]["c"]["o"] ) ) self.failUnless( c.dstNodule().plug().isSame( script["n"]["c"]["i"] ) )
def testNodeGadgetMetadataChanges( self ) : s = Gaffer.ScriptNode() g = GafferUI.GraphGadget( s ) s["n1"] = GafferTest.AddNode() s["n2"] = GafferTest.AddNode() s["n2"]["op1"].setInput( s["n1"]["sum"] ) def assertBothVisible() : ng1 = g.nodeGadget( s["n1"] ) ng2 = g.nodeGadget( s["n2"] ) c = g.connectionGadget( s["n2"]["op1"] ) self.assertTrue( isinstance( ng1, GafferUI.StandardNodeGadget ) ) self.assertTrue( isinstance( ng2, GafferUI.StandardNodeGadget ) ) self.assertTrue( isinstance( c, GafferUI.StandardConnectionGadget ) ) self.assertTrue( c.srcNodule().isSame( ng1.nodule( s["n1"]["sum"] ) ) ) self.assertTrue( c.dstNodule().isSame( ng2.nodule( s["n2"]["op1"] ) ) ) assertBothVisible() Gaffer.Metadata.registerValue( s["n1"], "nodeGadget:type", "" ) def assertN1Hidden() : ng1 = g.nodeGadget( s["n1"] ) ng2 = g.nodeGadget( s["n2"] ) c = g.connectionGadget( s["n2"]["op1"] ) self.assertTrue( ng1 is None ) self.assertTrue( isinstance( ng2, GafferUI.StandardNodeGadget ) ) self.assertTrue( isinstance( c, GafferUI.StandardConnectionGadget ) ) self.assertTrue( c.srcNodule() is None ) self.assertTrue( c.dstNodule().isSame( ng2.nodule( s["n2"]["op1"] ) ) ) assertN1Hidden() Gaffer.Metadata.registerValue( s["n2"], "nodeGadget:type", "" ) def assertBothHidden() : self.assertTrue( g.nodeGadget( s["n1"] ) is None ) self.assertTrue( g.nodeGadget( s["n2"] ) is None ) self.assertTrue( g.connectionGadget( s["n2"]["op1"] ) is None ) assertBothHidden() Gaffer.Metadata.registerValue( s["n2"], "nodeGadget:type", "GafferUI::StandardNodeGadget" ) assertN1Hidden() Gaffer.Metadata.registerValue( s["n1"], "nodeGadget:type", "GafferUI::StandardNodeGadget" ) assertBothVisible()
def testCanPositionNodeWithinBackdrop( self ) : s = Gaffer.ScriptNode() s["b"] = Gaffer.Backdrop() s["n"] = Gaffer.Node() g = GafferUI.GraphGadget( s ) backdropBound = g.nodeGadget( s["b"] ).transformedBound( g ) fallbackPosition = IECore.V2f( backdropBound.center().x, backdropBound.center().y ) g.getLayout().positionNode( g, s["n"], fallbackPosition ) self.assertEqual( g.getNodePosition( s["n"] ), fallbackPosition )
def testNoDuplicatePositionPlugsAfterPasting(self): script = Gaffer.ScriptNode() script["n"] = Gaffer.Node() g = GafferUI.GraphGadget(script) script.execute( script.serialise(script, Gaffer.StandardSet([script["n"]]))) self.assertTrue("__uiPosition" in script["n1"]) self.assertFalse("__uiPosition1" in script["n1"])
def testDisabledNodulesForPromotedPlugs(self): s = Gaffer.ScriptNode() g = GafferUI.GraphGadget(s) s["b"] = Gaffer.Box() s["b"]["n"] = self.NodulePositionNode() boxGadget = g.nodeGadget(s["b"]) p = Gaffer.PlugAlgo.promote(s["b"]["n"]["op2"]) self.assertEqual(boxGadget.nodule(p), None)
def testChangeNodeGadgetForUnviewedNode( self ) : s = Gaffer.ScriptNode() s["b"] = Gaffer.Box() s["b"]["n"] = Gaffer.Node() g = GafferUI.GraphGadget( s ) self.assertIsNotNone( g.nodeGadget( s["b"] ) ) self.assertIsNone( g.nodeGadget( s["b"]["n"] ) ) Gaffer.Metadata.registerValue( s["b"]["n"], "nodeGadget:type", "GafferUI::AuxiliaryNodeGadget" ) self.assertIsNone( g.nodeGadget( s["b"]["n"] ) )
def get_hierarchy_nodes(startnode, scriptnode, type_filter=HierarchyTask): connected = Gaffer.StandardSet() graphgadget = GafferUI.GraphGadget(scriptnode) if graphgadget is not None: connected.add([g.node() for g in graphgadget.connectedNodeGadgets( startnode, Gaffer.Plug.Direction.Out, sys.maxint ) if isinstance(g.node(), type_filter)]) if isinstance(startnode, type_filter): connected.add(startnode) return connected
def testRemoveNonNodulePlug( self ) : s = Gaffer.ScriptNode() s["n"] = Gaffer.Node() s["n"]["p"] = Gaffer.Plug() Gaffer.Metadata.registerPlugValue( s["n"]["p"], "nodule:type", "" ) g = GafferUI.GraphGadget( s ) self.assertTrue( g.nodeGadget( s["n"] ).nodule( s["n"]["p"] ) is None ) # Once upon a time, this would crash. del s["n"]["p"]
def testNodulePositions(self): s = Gaffer.ScriptNode() g = GafferUI.GraphGadget(s) s["a"] = GafferTest.AddNode() s["n"] = self.NodulePositionNode() s["r"] = GafferTest.AddNode() s["n"]["op1"].setInput(s["a"]["sum"]) s["r"]["op1"].setInput(s["n"]["sum"]) box = Gaffer.Box.create(s, Gaffer.StandardSet([s["n"]])) boxGadget = g.nodeGadget(box) self.assertEqual( boxGadget.connectionTangent(boxGadget.nodule(box["op1"])), imath.V3f(-1, 0, 0)) self.assertEqual( boxGadget.connectionTangent(boxGadget.nodule(box["sum"])), imath.V3f(1, 0, 0)) # Now test that a copy/paste of the box maintains the tangents in the copy. s2 = Gaffer.ScriptNode() g2 = GafferUI.GraphGadget(s2) s2.execute(s.serialise()) box2 = s2[box.getName()] boxGadget2 = g2.nodeGadget(box2) self.assertEqual( boxGadget2.connectionTangent(boxGadget2.nodule(box2["op1"])), imath.V3f(-1, 0, 0)) self.assertEqual( boxGadget2.connectionTangent(boxGadget2.nodule(box2["sum"])), imath.V3f(1, 0, 0))
def testNoFilter( self ) : s = Gaffer.ScriptNode() s["n1"] = Gaffer.Node() g = GafferUI.GraphGadget( s ) self.assertTrue( g.getRoot().isSame( s ) ) self.assertTrue( g.getFilter() is None ) self.assertTrue( g.nodeGadget( s["n1"] ) ) s["n2"] = Gaffer.Node() self.assertTrue( g.nodeGadget( s["n1"] ) )
def testIgnoreConnectionsFromSelf(self): script = Gaffer.ScriptNode() script["n"] = Gaffer.Node() script["n"]["p1"] = Gaffer.Plug(flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic) script["n"]["p2"] = Gaffer.Plug(flags=Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic) script["n"]["p2"].setInput(script["n"]["p1"]) g = GafferUI.GraphGadget(script) self.assertFalse(g.auxiliaryConnectionsGadget().hasConnection( script["n"], script["n"]))
def testLayoutAccessors( self ) : s = Gaffer.ScriptNode() g = GafferUI.GraphGadget( s ) l = g.getLayout() self.assertTrue( isinstance( l, GafferUI.StandardGraphLayout ) ) l2 = GafferUI.StandardGraphLayout() g.setLayout( l2 ) self.assertTrue( g.getLayout().isSame( l2 ) ) g.setLayout( l ) self.assertTrue( g.getLayout().isSame( l ) )
def testRemovedNodesDontHaveGadgets( self ) : s = Gaffer.ScriptNode() g = GafferUI.GraphGadget( s ) n = GafferTest.AddNode() s["add1"] = n self.failUnless( g.nodeGadget( n ) is not None ) s.deleteNodes( filter = Gaffer.StandardSet( [ n ] ) ) self.failUnless( g.nodeGadget( n ) is None )
def testCreateWithFilter( self ) : script = Gaffer.ScriptNode() script["add1"] = GafferTest.AddNode() script["add2"] = GafferTest.AddNode() nodeFilter = Gaffer.StandardSet( [ script["add2"] ] ) g = GafferUI.GraphGadget( script, nodeFilter ) self.failIf( g.nodeGadget( script["add1"] ) ) self.failUnless( g.nodeGadget( script["add2"] ) )
def __init__( self, scriptNode, **kw ) : # We want to disable precise navigation motions as they interfere # with our keyboard shortcuts and aren't that useful in the graph viewportGadget = GafferUI.ViewportGadget() viewportGadget.setPreciseMotionAllowed( False ) viewportGadget.setMaxPlanarZoom( imath.V2f( 25 ) ) self.__gadgetWidget = GafferUI.GadgetWidget( gadget = viewportGadget, bufferOptions = set( [ GafferUI.GLWidget.BufferOptions.Double, ] ), ) GafferUI.Editor.__init__( self, self.__gadgetWidget, scriptNode, **kw ) graphGadget = GafferUI.GraphGadget( self.scriptNode() ) self.__rootChangedConnection = graphGadget.rootChangedSignal().connect( Gaffer.WeakMethod( self.__rootChanged ) ) self.__gadgetWidget.getViewportGadget().setPrimaryChild( graphGadget ) self.__gadgetWidget.getViewportGadget().setDragTracking( GafferUI.ViewportGadget.DragTracking.XDragTracking | GafferUI.ViewportGadget.DragTracking.YDragTracking ) self.__frame( scriptNode.selection() ) self.__gadgetWidget.buttonPressSignal().connect( Gaffer.WeakMethod( self.__buttonPress ), scoped = False ) self.__gadgetWidget.keyPressSignal().connect( Gaffer.WeakMethod( self.__keyPress ), scoped = False ) self.__gadgetWidget.buttonDoubleClickSignal().connect( Gaffer.WeakMethod( self.__buttonDoubleClick ), scoped = False ) self.dragEnterSignal().connect( Gaffer.WeakMethod( self.__dragEnter ), scoped = False ) self.dragLeaveSignal().connect( Gaffer.WeakMethod( self.__dragLeave ), scoped = False ) self.dropSignal().connect( Gaffer.WeakMethod( self.__drop ), scoped = False ) self.__gadgetWidget.getViewportGadget().preRenderSignal().connect( Gaffer.WeakMethod( self.__preRender ), scoped = False ) with GafferUI.ListContainer( borderWidth = 8, spacing = 0 ) as overlay : with GafferUI.ListContainer( GafferUI.ListContainer.Orientation.Horizontal, parenting = { "verticalAlignment" : GafferUI.VerticalAlignment.Top, } ) : GafferUI.Spacer( imath.V2i( 1 ) ) GafferUI.MenuButton( image = "annotations.png", hasFrame = False, menu = GafferUI.Menu( Gaffer.WeakMethod( self.__annotationsMenu ), title = "Annotations" ) ) self.__gadgetWidget.addOverlay( overlay ) self.__nodeMenu = None
def testNoExtraPlugsAfterCopyPaste(self): script = Gaffer.ScriptNode() script["b"] = Gaffer.Backdrop() script["n"] = Gaffer.Node() graphGadget = GafferUI.GraphGadget(script) backdropGadget = graphGadget.nodeGadget(script["b"]) self.assertIsInstance(backdropGadget, GafferUI.BackdropNodeGadget) backdropGadget.frame([script["n"]]) script.execute( script.serialise(filter=Gaffer.StandardSet([script["b"]]))) self.assertEqual(script["b1"].keys(), script["b"].keys())
def testConnectNodes( self ) : s = Gaffer.ScriptNode() s["add1"] = GafferTest.AddNode() s["add2"] = GafferTest.AddNode() s["add3"] = GafferTest.AddNode() s["add3"]["op1"].setInput( s["add2"]["sum"] ) g = GafferUI.GraphGadget( s ) g.getLayout().connectNodes( g, Gaffer.StandardSet( [ s["add3"], s["add2"] ] ), Gaffer.StandardSet( [ s["add1"] ] ) ) self.assertTrue( s["add2"]["op1"].getInput().isSame( s["add1"]["sum"] ) )
def testUpstreamNodeGadgets(self): script = Gaffer.ScriptNode() # a -> b -> c -> e -> f # ^ # | # d script["a"] = GafferTest.AddNode() script["b"] = GafferTest.AddNode() script["c"] = GafferTest.AddNode() script["d"] = GafferTest.AddNode() script["e"] = GafferTest.AddNode() script["f"] = GafferTest.AddNode() script["b"]["op1"].setInput(script["a"]["sum"]) script["c"]["op1"].setInput(script["b"]["sum"]) script["c"]["op2"].setInput(script["d"]["sum"]) script["e"]["op1"].setInput(script["c"]["sum"]) script["f"]["op1"].setInput(script["e"]["sum"]) g = GafferUI.GraphGadget(script) u = [ x.node().relativeName(script) for x in g.upstreamNodeGadgets(script["c"]) ] self.assertEqual(len(u), 3) self.assertEqual(set(u), set(["a", "b", "d"])) u = [ x.node().relativeName(script) for x in g.upstreamNodeGadgets(script["f"]) ] self.assertEqual(len(u), 5) self.assertEqual(set(u), set(["a", "b", "d", "c", "e"])) # filtered nodes should be ignored g.setFilter(Gaffer.StandardSet([script["f"], script["e"], script["a"]])) u = [ x.node().relativeName(script) for x in g.upstreamNodeGadgets(script["f"]) ] self.assertEqual(u, ["e"])
def testFilterIsChildSet( self ) : s = Gaffer.ScriptNode() s["n1"] = Gaffer.Node() g = GafferUI.GraphGadget( s, Gaffer.ChildSet( s ) ) self.assertTrue( g.nodeGadget( s["n1"] ) ) l = len( g ) s["n2"] = Gaffer.Node() self.assertTrue( g.nodeGadget( s["n2"] ) ) self.assertEqual( len( g ), l + 1 )
def testInsertDot(self): s = Gaffer.ScriptNode() s["n1"] = GafferTest.AddNode() s["n2"] = GafferTest.AddNode() s["n2"]["op1"].setInput(s["n1"]["sum"]) s["d"] = Gaffer.Dot() g = GafferUI.GraphGadget(s) g.getLayout().connectNode(g, s["d"], Gaffer.StandardSet([s["n1"]])) self.assertTrue(s["d"]["out"].source().isSame(s["n1"]["sum"])) self.assertTrue(s["n2"]["op1"].getInput().isSame(s["d"]["out"]))
def get_required_tasks(startnode, scriptnode): graphgadget = GafferUI.GraphGadget(scriptnode) assert graphgadget, "We need a proper graphgadget." def _reduce_hierarchy_levels(nodes): """ Reduces unnecessary hierarchy levels for those cases that there's only a single entry in a Tuple or List. In these cases the nesting does not add any useful information and can be ignored. """ if isinstance(nodes, List): while len(nodes) == 1: nodes = nodes[0] elif isinstance(nodes, Tuple): while (len(nodes)) == 1: nodes = nodes[0] if not isinstance(nodes, Tuple): nodes = Tuple(nodes) return nodes def _get_nodes(current): required_tasks = List([]) downstream_nodes = tuple([g.node() for g in graphgadget.connectedNodeGadgets( current, Gaffer.Plug.Direction.Out, 1 )]) # Sorting by the x position is the expected behaviour for serial execution. # We assume that the x ordering of downstream nodes is the determining # factor for execution order. downstream_nodes = sorted(downstream_nodes, key=lambda node: graphgadget.getNodePosition(node).x) for node in downstream_nodes: if isinstance(node, Gaffer.Dot): required_tasks.append(_reduce_hierarchy_levels(_get_nodes(node))) elif isinstance(node, Serial): required_tasks.append(_reduce_hierarchy_levels(Tuple(_get_nodes(node)))) elif isinstance(node, Parallel): required_tasks.append(_reduce_hierarchy_levels(List(_get_nodes(node)))) elif isinstance(node, (HierarchyTask, JobtronautTask)): required_tasks.append(node.getName()) return _reduce_hierarchy_levels(required_tasks) required_tasks = _get_nodes(startnode) # Make sure that we don't end up with a single required task without any wrapping List or Tuple return required_tasks if isinstance(required_tasks, (List, Tuple)) else [required_tasks]
def testPositionNodeFallback(self): s = Gaffer.ScriptNode() s["node1"] = LayoutNode() s["node2"] = LayoutNode() g = GafferUI.GraphGadget(s) g.setNodePosition(s["node1"], imath.V2f(10, 0)) g.getLayout().positionNode(g, s["node2"], imath.V2f(-10, -20)) self.assertEqual(g.getNodePosition(s["node1"]), imath.V2f(10, 0)) self.assertEqual(g.getNodePosition(s["node2"]), imath.V2f(-10, -20))
def testNodulePositionsForPromotedPlugs( self ) : s = Gaffer.ScriptNode() g = GafferUI.GraphGadget( s ) s["b"] = Gaffer.Box() s["b"]["n"] = self.NodulePositionNode() boxGadget = g.nodeGadget( s["b"] ) p1 = Gaffer.PlugAlgo.promote( s["b"]["n"]["op1"] ) p2 = Gaffer.PlugAlgo.promote( s["b"]["n"]["sum"] ) self.assertEqual( boxGadget.noduleTangent( boxGadget.nodule( p1 ) ), IECore.V3f( -1, 0, 0 ) ) self.assertEqual( boxGadget.noduleTangent( boxGadget.nodule( p2 ) ), IECore.V3f( 1, 0, 0 ) )
def testRemovedNodesDontHaveConnections( self ) : s = Gaffer.ScriptNode() n = GafferTest.AddNode() s["add1"] = n s["add2"] = GafferTest.AddNode() s["add1"]["op1"].setInput( s["add2"]["sum"] ) g = GafferUI.GraphGadget( s ) s.deleteNodes( filter = Gaffer.StandardSet( [ s["add1"] ] ) ) self.failIf( g.connectionGadget( n["op1"] ) )
def testConnectNodeInStream( self ) : s = Gaffer.ScriptNode() s["a1"] = GafferScene.ShaderAssignment() s["a2"] = GafferScene.ShaderAssignment() s["a3"] = GafferScene.ShaderAssignment() s["a2"]["in"].setInput( s["a1"]["out"] ) g = GafferUI.GraphGadget( s ) g.getLayout().connectNode( g, s["a3"], Gaffer.StandardSet( [ s["a1"] ] ) ) self.assertTrue( s["a3"]["in"].getInput().isSame( s["a1"]["out"] ) ) self.assertTrue( s["a2"]["in"].getInput().isSame( s["a3"]["out"] ) )
def testSeparateNetworks(self): s = Gaffer.ScriptNode() s["top1"] = LayoutNode() s["bottom1"] = LayoutNode() s["bottom1"]["top0"].setInput(s["top1"]["bottom0"]) s["top2"] = LayoutNode() s["bottom2"] = LayoutNode() s["bottom2"]["top0"].setInput(s["top2"]["bottom0"]) g = GafferUI.GraphGadget(s) g.getLayout().layoutNodes(g) self.assertNoOverlaps(g)