def testNamePlugAffects(self): d = GafferScene.Duplicate() cs = GafferTest.CapturingSlot(d.plugDirtiedSignal()) d["name"].setValue("test") self.assertTrue(d["out"]["childNames"] in [c[0] for c in cs])
def testSets(self): s = GafferScene.Sphere() s["sets"].setValue("set") g = GafferScene.Group() g["in"].setInput(s["out"]) d = GafferScene.Duplicate() d["in"].setInput(g["out"]) d["target"].setValue("/group") d["copies"].setValue(5) self.assertEqual( set(d["out"].set("set").value.paths()), set(["/group/sphere"] + ["/group%d/sphere" % n for n in range(1, 6)])) d["target"].setValue("/group/sphere") d["copies"].setValue(1500) self.assertEqual( set(d["out"].set("set").value.paths()), set(["/group/sphere"] + ["/group/sphere%d" % n for n in range(1, 1501)]))
def testMultipleCopies(self): s = GafferScene.Sphere() d = GafferScene.Duplicate() d["in"].setInput(s["out"]) d["target"].setValue("/sphere") d["transform"]["translate"].setValue(IECore.V3f(1, 0, 0)) d["copies"].setValue(10) self.assertSceneValid(d["out"]) self.assertEqual( d["out"].childNames("/"), IECore.InternedStringVectorData( ["sphere"] + ["sphere%d" % x for x in range(1, 11)])) for i in range(1, 11): path = "sphere%d" % i self.assertPathHashesEqual(d["out"], "/sphere", d["out"], path, childPlugNamesToIgnore=("transform", )) self.assertEqual( d["out"].transform(path), IECore.M44f.createTranslated(IECore.V3f(1, 0, 0) * i))
def testTwoRenders( self ) : sphere = GafferScene.Sphere() duplicate = GafferScene.Duplicate() duplicate["in"].setInput( sphere["out"] ) duplicate["target"].setValue( "/sphere" ) duplicate["copies"].setValue( 10000 ) render = GafferArnold.ArnoldRender() render["in"].setInput( duplicate["out"] ) render["mode"].setValue( render.Mode.SceneDescriptionMode ) render["fileName"].setValue( self.temporaryDirectory() + "/test.####.ass" ) errors = [] def executeFrame( frame ) : with Gaffer.Context() as c : c.setFrame( frame ) try : render["task"].execute() except Exception as e : errors.append( str( e ) ) threads = [] for i in range( 0, 2 ) : t = threading.Thread( target = executeFrame, args = ( i, ) ) t.start() threads.append( t ) for t in threads : t.join() self.assertEqual( len( errors ), 1 ) self.assertTrue( "Arnold is already in use" in errors[0] )
def testInvalidTarget(self): s = GafferScene.Sphere() d = GafferScene.Duplicate() d["in"].setInput(s["out"]) d["target"].setValue("/cube") self.assertRaises(RuntimeError, d["out"].childNames, "/")
def testInvalidTarget(self): s = GafferScene.Sphere() d = GafferScene.Duplicate() d["in"].setInput(s["out"]) d["target"].setValue("/cube") self.assertSceneValid(d["out"]) self.assertScenesEqual(d["out"], d["in"])
def testInvalidTargetParent(self): r = GafferScene.SceneReader() r["fileName"].setValue( "${GAFFER_ROOT}/python/GafferSceneTest/alembicFiles/cube.abc") d = GafferScene.Duplicate() d["in"].setInput(r["out"]) d["target"].setValue("/notGroup1/pCube1") self.assertScenesEqual(d["in"], d["out"])
def testPerformance(self): sphere = GafferScene.Sphere() duplicate = GafferScene.Duplicate() duplicate["in"].setInput(sphere["out"]) duplicate["target"].setValue("/sphere") duplicate["transform"]["translate"]["x"].setValue(2) duplicate["copies"].setValue(100000) with GafferTest.TestRunner.PerformanceScope(): GafferSceneTest.traverseScene(duplicate["out"])
def test( self ) : s = GafferScene.Sphere() d = GafferScene.Duplicate() d["in"].setInput( s["out"] ) d["target"].setValue( "/sphere" ) d["transform"]["translate"].setValue( IECore.V3f( 1, 0, 0 ) ) self.assertSceneValid( d["out"] ) self.assertEqual( d["out"].childNames( "/" ), IECore.InternedStringVectorData( [ "sphere", "sphere1" ] ) ) self.assertPathHashesEqual( s["out"], "/sphere", d["out"], "/sphere" ) self.assertPathHashesEqual( d["out"], "/sphere", d["out"], "/sphere1", childPlugNamesToIgnore = ( "transform", ) ) self.assertEqual( d["out"].transform( "/sphere1" ), IECore.M44f.createTranslated( IECore.V3f( 1, 0, 0 ) ) )
def testCapsules(self): s = Gaffer.ScriptNode() s["sphere"] = GafferScene.Sphere("sphere") s["sphere1"] = GafferScene.Sphere("sphere1") s["group"] = GafferScene.Group("group") s["group"]["in"][0].setInput(s["sphere"]["out"]) s["group"]["in"][1].setInput(s["sphere1"]["out"]) s["path_filter"] = GafferScene.PathFilter("path_filter") s["path_filter"]["paths"].setValue(IECore.StringVectorData(['*'])) s["encapsulate"] = GafferScene.Encapsulate("encapsulate") s["encapsulate"]["in"].setInput(s["group"]["out"]) s["encapsulate"]["filter"].setInput(s["path_filter"]["out"]) s["duplicate"] = GafferScene.Duplicate("duplicate") s["duplicate"]["in"].setInput(s["encapsulate"]["out"]) s["duplicate"]["target"].setValue('group') s["duplicate"]["copies"].setValue(2) s["render"] = GafferAppleseed.AppleseedRender() s["render"]["in"].setInput(s["duplicate"]["out"]) s["render"]["mode"].setValue(s["render"].Mode.SceneDescriptionMode) projectFilename = self.temporaryDirectory() + "/test.appleseed" s["render"]["fileName"].setValue(projectFilename) s["render"]["task"].execute() reader = asr.ProjectFileReader() options = asr.ProjectFileReaderOptions.OmitReadingMeshFiles project = reader.read(projectFilename, appleseedProjectSchemaPath(), options) scene = project.get_scene() mainAssembly = scene.assemblies().get_by_name("assembly") # Check that we have 3 instances of 1 capsule. self.assertEqual(len(mainAssembly.assemblies()), 1) self.assertEqual(len(mainAssembly.assembly_instances()), 3) capsuleAssemblyName = mainAssembly.assemblies().keys()[0] capsuleAssembly = mainAssembly.assemblies()[capsuleAssemblyName] # Check that we have 2 instances of 1 sphere inside the capsule. self.assertEqual(len(capsuleAssembly.assemblies()), 1) self.assertEqual(len(capsuleAssembly.assembly_instances()), 2)
def testManyCameras( self ) : camera = GafferScene.Camera() duplicate = GafferScene.Duplicate() duplicate["in"].setInput( camera["out"] ) duplicate["target"].setValue( "/camera" ) duplicate["copies"].setValue( 1000 ) render = GafferArnold.ArnoldRender() render["in"].setInput( duplicate["out"] ) render["mode"].setValue( render.Mode.SceneDescriptionMode ) render["fileName"].setValue( self.temporaryDirectory() + "/test.ass" ) render["task"].execute()
def testHierarchy( self ) : s = GafferScene.Sphere() g = GafferScene.Group() g["in"].setInput( s["out"] ) d = GafferScene.Duplicate() d["in"].setInput( g["out"] ) d["target"].setValue( "/group" ) self.assertSceneValid( d["out"] ) self.assertPathsEqual( d["out"], "/group", d["out"], "/group1" ) self.assertPathHashesEqual( d["out"], "/group", d["out"], "/group1", childPlugNamesToIgnore = ( "transform", ) ) self.assertPathsEqual( d["out"], "/group/sphere", d["out"], "/group1/sphere" ) self.assertPathHashesEqual( d["out"], "/group/sphere", d["out"], "/group1/sphere" )
def testSetNames(self): s = GafferScene.Sphere() s["sets"].setValue("testSet") d = GafferScene.Duplicate() d["in"].setInput(s["out"]) d["target"].setValue("/sphere") d["transform"]["translate"].setValue(imath.V3f(1, 0, 0)) with Gaffer.PerformanceMonitor() as m: self.assertEqual(s["out"]["setNames"].hash(), d["out"]["setNames"].hash()) self.assertTrue(s["out"]["setNames"].getValue(_copy=False).isSame( d["out"]["setNames"].getValue(_copy=False))) self.assertEqual(s["out"]["setNames"].getValue(), IECore.InternedStringVectorData(["testSet"])) self.assertEqual(m.plugStatistics(d["out"]["setNames"]).hashCount, 0) self.assertEqual( m.plugStatistics(d["out"]["setNames"]).computeCount, 0)
def testPruneTarget(self): sphere = GafferScene.Sphere() sphereFilter = GafferScene.PathFilter() sphereFilter["paths"].setValue(IECore.StringVectorData(["/sphere"])) prune = GafferScene.Prune() prune["in"].setInput(sphere["out"]) duplicate = GafferScene.Duplicate() duplicate["in"].setInput(prune["out"]) duplicate["target"].setValue("/sphere") self.assertEqual( duplicate["out"].childNames("/"), IECore.InternedStringVectorData(["sphere", "sphere1"])) prune["filter"].setInput(sphereFilter["out"]) self.assertEqual(duplicate["out"].childNames("/"), IECore.InternedStringVectorData([]))
def testComputePerformance(self): sphere = GafferScene.Sphere() duplicate = GafferScene.Duplicate() duplicate["in"].setInput(sphere["out"]) duplicate["target"].setValue('/sphere') duplicate["copies"].setValue(1000000) pathFilter = GafferScene.PathFilter() pathFilter["paths"].setValue(IECore.StringVectorData(['...'])) filterResults = GafferScene.FilterResults() filterResults["scene"].setInput(duplicate["out"]) filterResults["filter"].setInput(pathFilter["out"]) # Evaluate the root childNames beforehand to focus our timing on the compute duplicate["out"].childNames("/") with GafferTest.TestRunner.PerformanceScope(): filterResults["out"].getValue()
def testHierarchy(self): s = GafferScene.Sphere() g = GafferScene.Group() g["in"][0].setInput(s["out"]) d = GafferScene.Duplicate() d["in"].setInput(g["out"]) d["target"].setValue("/group") self.assertSceneValid(d["out"]) self.assertPathsEqual(d["out"], "/group", d["out"], "/group1") self.assertPathHashesEqual(d["out"], "/group", d["out"], "/group1", checks=self.allPathChecks - {"transform"}) self.assertPathsEqual(d["out"], "/group/sphere", d["out"], "/group1/sphere") self.assertPathHashesEqual(d["out"], "/group/sphere", d["out"], "/group1/sphere")
def test(self): s = GafferScene.Sphere() d = GafferScene.Duplicate() d["in"].setInput(s["out"]) d["target"].setValue("/sphere") d["transform"]["translate"].setValue(imath.V3f(1, 0, 0)) self.assertSceneValid(d["out"]) self.assertEqual( d["out"].childNames("/"), IECore.InternedStringVectorData(["sphere", "sphere1"])) self.assertPathHashesEqual(s["out"], "/sphere", d["out"], "/sphere") self.assertPathHashesEqual(d["out"], "/sphere", d["out"], "/sphere1", checks=self.allPathChecks - {"transform"}) self.assertEqual(d["out"].transform("/sphere1"), imath.M44f().translate(imath.V3f(1, 0, 0)))
def testNamePlug(self): s = GafferScene.Sphere() g = GafferScene.Group() g["in"][0].setInput(s["out"]) d = GafferScene.Duplicate() d["in"].setInput(g["out"]) d["target"].setValue("/group/sphere") for target, name, copies, childNames in [ ("sphere", "", 1, ["sphere", "sphere1"]), ("sphere", "", 2, ["sphere", "sphere1", "sphere2"]), ("sphere", "copy", 2, ["sphere", "copy1", "copy2"]), ("sphere", "copy", 1, ["sphere", "copy"]), ("sphere", "sphere", 1, ["sphere", "sphere1"]), ("sphere", "sphere", 2, ["sphere", "sphere1", "sphere2"]), ("sphere", "copy10", 2, ["sphere", "copy10", "copy11"]), ("sphere", "copy10", 1, ["sphere", "copy10"]), ("sphere1", "copy10", 1, ["sphere1", "copy10"]), ("sphere1", "sphere10", 1, ["sphere1", "sphere10"]), ("sphere1", "sphere10", 2, ["sphere1", "sphere10", "sphere11"]), ("sphere12", "sphere10", 1, ["sphere12", "sphere10"]), ("sphere12", "sphere10", 2, ["sphere12", "sphere10", "sphere11"]), ("sphere12", "sphere11", 2, ["sphere12", "sphere11", "sphere13"]), ("sphere12", "copy", 1, ["sphere12", "copy"]), ("sphere12", "copy2", 1, ["sphere12", "copy2"]), ("sphere12", "copy2", 2, ["sphere12", "copy2", "copy3"]), ("sphere12", "sphere12", 1, ["sphere12", "sphere13"]), ("sphere12", "sphere12", 2, ["sphere12", "sphere13", "sphere14"]), ]: s["name"].setValue(target) d["target"].setValue("/group/" + target) d["name"].setValue(name) d["copies"].setValue(copies) self.assertSceneValid(d["out"]) self.assertEqual(d["out"].childNames("/group"), IECore.InternedStringVectorData(childNames))
def testFilter(self): cube = GafferScene.Cube() cube["sets"].setValue("boxes") sphere = GafferScene.Sphere() group = GafferScene.Group() group["in"][0].setInput(cube["out"]) group["in"][1].setInput(sphere["out"]) filter = GafferScene.PathFilter() filter["paths"].setValue(IECore.StringVectorData(["/group/*"])) duplicate = GafferScene.Duplicate() duplicate["in"].setInput(group["out"]) duplicate["filter"].setInput(filter["out"]) self.assertSceneValid(duplicate["out"]) self.assertEqual( duplicate["out"].childNames("/group"), IECore.InternedStringVectorData([ "cube", "sphere", "cube1", "sphere1", ])) self.assertPathsEqual(duplicate["out"], "/group/cube", duplicate["in"], "/group/cube") self.assertPathsEqual(duplicate["out"], "/group/sphere", duplicate["in"], "/group/sphere") self.assertPathsEqual(duplicate["out"], "/group/cube1", duplicate["in"], "/group/cube") self.assertPathsEqual(duplicate["out"], "/group/sphere1", duplicate["in"], "/group/sphere") self.assertEqual(duplicate["out"].set("boxes").value, IECore.PathMatcher(["/group/cube", "/group/cube1"]))
def testExistingTransform(self): cube = GafferScene.Cube() cube["transform"]["translate"]["x"].setValue(1) filter = GafferScene.PathFilter() filter["paths"].setValue(IECore.StringVectorData(["/cube"])) duplicate = GafferScene.Duplicate() duplicate["in"].setInput(cube["out"]) duplicate["filter"].setInput(filter["out"]) duplicate["transform"]["translate"]["x"].setValue(2) self.assertSceneValid(duplicate["out"]) self.assertEqual(duplicate["out"].transform("/cube1"), imath.M44f().translate(imath.V3f(3, 0, 0))) duplicate["transform"]["translate"]["x"].setValue(4) self.assertSceneValid(duplicate["out"]) self.assertEqual(duplicate["out"].transform("/cube1"), imath.M44f().translate(imath.V3f(5, 0, 0)))
def test( self ) : # - groupA # - group1 # - sphere # - cube # - group2 # - sphere # - cube # - sometimesCube # - group3 # - sphere # - cube # - group4 # - sphere # - cube box = Gaffer.Node() box["sphere"] = GafferScene.Sphere() box["sphere"]["sets"].setValue( "sphereSet" ) box["cube"] = GafferScene.Cube() box["cube"]["sets"].setValue( "cubeSet" ) box["sometimesCube"] = GafferScene.Cube() box["sometimesCube"]["name"].setValue( "sometimesCube" ) box["sometimesCube"]["sets"].setValue( "cubeSet" ) box["group"] = GafferScene.Group() box["group"]["in"][0].setInput( box["sphere"]["out"] ) box["group"]["in"][1].setInput( box["cube"]["out"] ) box["group"]["in"][1].setInput( box["sometimesCube"]["out"] ) box["e"] = Gaffer.Expression() box["e"].setExpression( inspect.cleandoc( """ n = context["collect:rootName"] i = int( n[-1] ) - 1 parent["sphere"]["radius"] = 1 + i * 0.1 parent["sphere"]["transform"]["translate"] = imath.V3f( 1 + i, 0, 0 ) parent["cube"]["transform"]["translate"] = imath.V3f( 0, 1 + i, 0 ) parent["sometimesCube"]["enabled"] = n == "group2" parent["group"]["transform"]["translate"] = imath.V3f( 0, 0, 1 + i ) """ ) ) collect = GafferScene.CollectScenes() collect["in"].setInput( box["group"]["out"] ) collect["rootNames"].setValue( IECore.StringVectorData( [ "group1", "group2", "group3", "group4" ] ) ) collect["sourceRoot"].setValue( "/group" ) groupA = GafferScene.Group() groupA["name"].setValue( "groupA" ) groupA["in"][0].setInput( collect["out"] ) encapsulateFilter = GafferScene.PathFilter() encapsulateFilter["paths"].setValue( IECore.StringVectorData( [ "/groupA/*" ] ) ) encapsulateCollect = GafferScene.Encapsulate() encapsulateCollect["in"].setInput( groupA["out"] ) encapsulateCollect["filter"].setInput( encapsulateFilter["out"] ) preEncapsulateFilter = GafferScene.PathFilter() preEncapsulateFilter["paths"].setValue( IECore.StringVectorData( [ "/group" ] ) ) preEncapsulate = GafferScene.Encapsulate() preEncapsulate["in"].setInput( box["group"]["out"] ) preEncapsulate["filter"].setInput( preEncapsulateFilter["out"] ) collectEncapsulate = GafferScene.CollectScenes() collectEncapsulate["in"].setInput( preEncapsulate["out"] ) collectEncapsulate["rootNames"].setValue( IECore.StringVectorData( [ "group1", "group2", "group3", "group4" ] ) ) collectEncapsulate["sourceRoot"].setValue( "/group" ) collectEncapsulateGroup = GafferScene.Group() collectEncapsulateGroup["name"].setValue( "groupA" ) collectEncapsulateGroup["in"][0].setInput( collectEncapsulate["out"] ) unencapsulateFilter = GafferScene.PathFilter() unencapsulate1 = GafferScene.Unencapsulate() unencapsulate1["in"].setInput( encapsulateCollect["out"] ) unencapsulate1["filter"].setInput( unencapsulateFilter["out"] ) unencapsulate2 = GafferScene.Unencapsulate() unencapsulate2["in"].setInput( collectEncapsulateGroup["out"] ) unencapsulate2["filter"].setInput( unencapsulateFilter["out"] ) # We can reverse the encapsulate by unencapsulating everything unencapsulateFilter["paths"].setValue( IECore.StringVectorData( [ "..." ] ) ) self.assertScenesEqual( groupA["out"], unencapsulate1["out"] ) # Unencapsulate should work the same whether the capsules come from before or after the collect self.assertScenesEqual( unencapsulate1["out"], unencapsulate2["out"] ) # Or just unencapsulate one thing unencapsulateFilter["paths"].setValue( IECore.StringVectorData( [ "/groupA/group3" ] ) ) self.assertScenesEqual( encapsulateCollect["out"], unencapsulate1["out"], pathsToPrune = [ "/groupA/group3" ] ) self.assertScenesEqual( groupA["out"], unencapsulate1["out"], pathsToPrune = [ "/groupA/group1", "/groupA/group2", "/groupA/group4" ] ) # Whichever place we encapsulate, we still get the same results, except that the capsule objects themselves # which weren't encapsulated will appear different ( because they were computed in different places, and # reference different source plugs self.assertScenesEqual( unencapsulate1["out"], unencapsulate2["out"], checks = self.allSceneChecks - { "object" } ) self.assertScenesEqual( unencapsulate1["out"], unencapsulate2["out"], pathsToPrune = [ "/groupA/group1", "/groupA/group2", "/groupA/group4" ] ) unencapsulateFilter["paths"].setValue( IECore.StringVectorData( [ "..." ] ) ) # Test modifying the hierarchy after making capsules by duplicating a location duplicate = GafferScene.Duplicate() duplicate["target"].setValue( "/groupA/group3" ) duplicate["in"].setInput( collectEncapsulateGroup["out"] ) unencapsulateDuplicated = GafferScene.Unencapsulate() unencapsulateDuplicated["in"].setInput( duplicate["out"] ) unencapsulateDuplicated["filter"].setInput( unencapsulateFilter["out"] ) # This copies group3 as group5 self.assertEqual( unencapsulateDuplicated["out"].fullTransform( "/groupA/group5/sphere" ), groupA["out"].fullTransform( "/groupA/group3/sphere" ) ) # Sanity check that groups do have unique transforms self.assertNotEqual( unencapsulateDuplicated["out"].fullTransform( "/groupA/group5/sphere" ), groupA["out"].fullTransform( "/groupA/group4/sphere" ) ) # This should be same result as copying group3 to group5 without any encapsulation preDuplicate = GafferScene.Duplicate() preDuplicate["target"].setValue( "/groupA/group3" ) preDuplicate["in"].setInput( groupA["out"] ) self.assertScenesEqual( unencapsulateDuplicated["out"], preDuplicate["out"] ) # Some tests where we merge an extra location into the scene amongst the capsules, # which should give the same result whether it's done before or after unencapsulating extraSphere = GafferScene.Sphere() extraSphere["name"].setValue( "extra" ) extraSphere["sets"].setValue( "sphereSet" ) extraSpherePostParent = GafferScene.Parent() extraSpherePostParent["in"].setInput( unencapsulate2["out"] ) extraSpherePostParent["children"][0].setInput( extraSphere["out"] ) extraSpherePreParent = GafferScene.Parent() extraSpherePreParent["in"].setInput( collectEncapsulateGroup["out"] ) extraSpherePreParent["children"][0].setInput( extraSphere["out"] ) unencapsulateAfter = GafferScene.Unencapsulate() unencapsulateAfter["in"].setInput( extraSpherePreParent["out"] ) unencapsulateAfter["filter"].setInput( unencapsulateFilter["out"] ) # Test parenting in a sphere at a the same level as a capsule extraSpherePostParent["parent"].setValue( "/groupA" ) extraSpherePreParent["parent"].setValue( "/groupA" ) self.assertScenesEqual( extraSpherePostParent["out"], unencapsulateAfter["out"], checks = self.allSceneChecks - { "childNames" } ) # Test a weird case: parenting the sphere under a capsule, so that when the capsule is expanded, # it gets merged with the children of the capsule. It's arguable that this shouldn't need to # work, and maybe there would be some extra optimizations available if it wasn't allowed, but for # the moment, it works extraSpherePostParent["parent"].setValue( "/groupA/group2" ) extraSpherePreParent["parent"].setValue( "/groupA/group2" ) self.assertScenesEqual( extraSpherePostParent["out"], unencapsulateAfter["out"], checks = self.allSceneChecks - { "childNames" } )
# BuildTarget: images/herd.png import imath import GafferScene import GafferUI scriptWindow = GafferUI.ScriptWindow.acquire( script ) script["Cow"] = GafferScene.SceneReader( "Cow" ) script["Cow"]["fileName"].setValue( "${GAFFER_ROOT}/resources/cow/cow.scc" ) script["Herd"] = GafferScene.Duplicate( "Herd" ) script["Herd"]["target"].setValue( '/cow' ) script["Herd"]["copies"].setValue( 7 ) script["Herd"]["transform"]["translate"].setValue( imath.V3f( 16, 0, 0 ) ) script["Herd"]["transform"]["rotate"].setValue( imath.V3f( 0, 45, 0 ) ) script["Herd"]["in"].setInput( script["Cow"]["out"] ) script.selection().add( script["Herd"] ) viewer = scriptWindow.getLayout().editors( GafferUI.Viewer )[0] GafferUI.WidgetAlgo.grab( widget = viewer, imagePath = "images/herd.png" )