def testSignalThreadSafety(self):

        script = Gaffer.ScriptNode()

        script["random"] = Gaffer.Random()
        script["random"]["contextEntry"].setValue("collect:rootName")

        script["sphere"] = GafferScene.Sphere()
        script["sphere"]["radius"].setInput(script["random"]["outFloat"])

        script["filter"] = GafferScene.PathFilter()
        script["filter"]["paths"].setValue(IECore.StringVectorData(["/sphere"
                                                                    ]))

        script["encapsulate"] = GafferScene.Encapsulate()
        script["encapsulate"]["in"].setInput(script["sphere"]["out"])
        script["encapsulate"]["filter"].setInput(script["filter"]["out"])

        script["collect"] = GafferScene.CollectScenes()
        script["collect"]["in"].setInput(script["encapsulate"]["out"])
        script["collect"]["rootNames"].setValue(
            IECore.StringVectorData([str(x) for x in range(0, 100)]))

        script["fileName"].setValue(
            os.path.join(self.temporaryDirectory(), "test.gfr"))
        script.save()

        # This exposed a crash caused by non-threadsafe access to signals from Capsules. It
        # will throw if the subprocess crashes.
        subprocess.check_output([
            "gaffer", "stats", script["fileName"].getValue(), "-scene",
            "collect"
        ])
Beispiel #2
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)
Beispiel #3
0
	def testCapsuleHash( self ) :

		sphere = GafferScene.Sphere()
		group1 = GafferScene.Group()
		group1["in"][0].setInput( sphere["out"] )
		group2 = GafferScene.Group()
		group2["in"][0].setInput( group1["out"] )

		pathFilter = GafferScene.PathFilter()
		pathFilter["paths"].setValue( IECore.StringVectorData( [ "/group/group" ] ) )

		encapsulate = GafferScene.Encapsulate()
		encapsulate["in"].setInput( group2["out"] )
		encapsulate["filter"].setInput( pathFilter["out"] )

		objectHashes = set()
		capsuleHashes = set()

		def assertHashesUnique( path ) :

			objectHash = encapsulate["out"].objectHash( path )
			capsule = encapsulate["out"].object( path )
			self.assertIsInstance( capsule, GafferScene.Capsule )
			capsuleHash = capsule.hash()

			self.assertNotIn( objectHash, objectHashes )
			self.assertNotIn( capsuleHash, capsuleHashes )

			objectHashes.add( objectHash )
			capsuleHashes.add( capsuleHash )

		assertHashesUnique( "/group/group" )

		sphere["radius"].setValue( 2 )
		assertHashesUnique( "/group/group" )

		sphere["name"].setValue( "bigSphere" )
		assertHashesUnique( "/group/group" )

		sphere["transform"]["translate"]["x"].setValue( 1 )
		assertHashesUnique( "/group/group" )

		pathFilter["paths"].setValue( IECore.StringVectorData( [ "/group" ] ) )
		assertHashesUnique( "/group" )

		encapsulate["in"].setInput( group1["out"] )
		assertHashesUnique( "/group" )
	def testRootObject( self ) :

		sphere = GafferScene.Sphere()
		sphere["radius"].setValue( 42 )

		f = GafferScene.PathFilter()
		f["paths"].setValue( IECore.StringVectorData( [ "/sphere" ] ) )

		encapsulate= GafferScene.Encapsulate()
		encapsulate["in"].setInput( sphere["out"] )
		encapsulate["filter"].setInput( f["out"] )

		unencapsulate = GafferScene.Unencapsulate()
		unencapsulate["in"].setInput( encapsulate["out"] )
		unencapsulate["filter"].setInput( f["out"] )

		# Test unencapsulating the object at the root of the capsule
		self.assertScenesEqual( sphere["out"], unencapsulate["out"] )
Beispiel #5
0
	def testSetMemberAtRoot( self ) :

		sphere = GafferScene.Sphere()
		sphere["sets"].setValue( "A" )

		group = GafferScene.Group()
		group["in"][0].setInput( sphere["out"] )

		self.assertEqual( group["out"].set( "A" ).value.paths(), [ "/group/sphere" ] )

		pathFilter = GafferScene.PathFilter()
		pathFilter["paths"].setValue( IECore.StringVectorData( [ "/group/sphere" ] ) )

		encapsulate = GafferScene.Encapsulate()
		encapsulate["in"].setInput( group["out"] )
		encapsulate["filter"].setInput( pathFilter["out"] )

		self.assertEqual( encapsulate["out"].set( "A" ).value.paths(), [ "/group/sphere" ] )
Beispiel #6
0
	def testEncapsulateDeformationBlur( self ) :

		s = Gaffer.ScriptNode()

		# Make a sphere where the red channel has the value of the current frame.

		s["sphere"] = GafferScene.Sphere()

		s["sphereFilter"] = GafferScene.PathFilter()
		s["sphereFilter"]["paths"].setValue( IECore.StringVectorData( [ "/sphere" ] ) )

		s["frame"] = GafferTest.FrameNode()

		s["flat"] = GafferArnold.ArnoldShader()
		s["flat"].loadShader( "flat" )
		s["flat"]["parameters"]["color"].setValue( imath.Color3f( 0 ) )
		s["flat"]["parameters"]["color"]["r"].setInput( s["frame"]["output"] )

		s["assignment"] = GafferScene.ShaderAssignment()
		s["assignment"]["in"].setInput( s["sphere"]["out"] )
		s["assignment"]["shader"].setInput( s["flat"]["out"] )
		s["assignment"]["filter"].setInput( s["sphereFilter"]["out"] )

		# Put the sphere in a capsule.

		s["group"] = GafferScene.Group()
		s["group"]["in"][0].setInput( s["assignment"]["out"] )

		s["groupFilter"] = GafferScene.PathFilter()
		s["groupFilter"]["paths"].setValue( IECore.StringVectorData( [ "/group" ] ) )

		s["encapsulate"] = GafferScene.Encapsulate()
		s["encapsulate"]["in"].setInput( s["group"]["out"] )
		s["encapsulate"]["filter"].setInput( s["groupFilter"]["out"] )

		# Do a render at frame 1, with deformation blur off.

		s["outputs"] = GafferScene.Outputs()
		s["outputs"].addOutput(
			"beauty",
			IECoreScene.Output(
				os.path.join( self.temporaryDirectory(), "deformationBlurOff.exr" ),
				"exr",
				"rgba",
				{
				}
			)
		)
		s["outputs"]["in"].setInput( s["encapsulate"]["out"] )

		s["options"] = GafferScene.StandardOptions()
		s["options"]["in"].setInput( s["outputs"]["out"] )

		s["arnoldOptions"] = GafferArnold.ArnoldOptions()
		s["arnoldOptions"]["in"].setInput( s["options"]["out"] )
		s["arnoldOptions"]["options"]["aaSamples"]["enabled"].setValue( True )
		s["arnoldOptions"]["options"]["aaSamples"]["value"].setValue( 6 )

		s["render"] = GafferArnold.ArnoldRender()
		s["render"]["in"].setInput( s["arnoldOptions"]["out"] )
		s["render"]["task"].execute()

		# Do another render at frame 1, but with deformation blur on.

		s["options"]["options"]["deformationBlur"]["enabled"].setValue( True )
		s["options"]["options"]["deformationBlur"]["value"].setValue( True )
		s["options"]["options"]["shutter"]["enabled"].setValue( True )
		s["options"]["options"]["shutter"]["value"].setValue( imath.V2f( -0.5, 0.5 ) )
		s["outputs"]["outputs"][0]["fileName"].setValue( os.path.join( self.temporaryDirectory(), "deformationBlurOn.exr" ) )
		s["render"]["task"].execute()

		# Check that the renders are the same.

		s["deformationOff"] = GafferImage.ImageReader()
		s["deformationOff"]["fileName"].setValue( os.path.join( self.temporaryDirectory(), "deformationBlurOff.exr" ) )

		s["deformationOn"] = GafferImage.ImageReader()
		s["deformationOn"]["fileName"].setValue( os.path.join( self.temporaryDirectory(), "deformationBlurOn.exr" ) )

		# The `maxDifference` is huge to account for noise and watermarks, but is still low enough to check what
		# we want, since if the Encapsulate was sampled at shutter open and not the frame, the difference would be
		# 0.5.
		self.assertImagesEqual( s["deformationOff"]["out"], s["deformationOn"]["out"], maxDifference = 0.25, ignoreMetadata = True )
	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" } )
    def test(self):

        # - groupA
        #    - groupB
        #       - sphere
        #       - cube
        #    - sphere

        sphere = GafferScene.Sphere()
        sphere["sets"].setValue("sphereSet")

        cube = GafferScene.Cube()
        cube["sets"].setValue("cubeSet")

        groupB = GafferScene.Group()
        groupB["in"][0].setInput(sphere["out"])
        groupB["in"][1].setInput(cube["out"])
        groupB["name"].setValue("groupB")

        groupA = GafferScene.Group()
        groupA["in"][0].setInput(groupB["out"])
        groupA["in"][1].setInput(sphere["out"])
        groupA["name"].setValue("groupA")

        # When there is no filter attached, the node
        # should be an exact pass-through.

        encapsulate = GafferScene.Encapsulate()
        encapsulate["in"].setInput(groupA["out"])

        self.assertSceneHashesEqual(encapsulate["out"],
                                    groupA["out"],
                                    checks=self.allSceneChecks - {"sets"})
        self.assertScenesEqual(encapsulate["out"], groupA["out"])

        # The same goes if there is a filter but it
        # doesn't match anything.

        pathFilter = GafferScene.PathFilter()
        encapsulate["filter"].setInput(pathFilter["out"])

        self.assertSceneHashesEqual(encapsulate["out"],
                                    groupA["out"],
                                    checks=self.allSceneChecks - {"sets"})
        self.assertScenesEqual(encapsulate["out"], groupA["out"])

        # Even when the filter does match something, the
        # unmatched paths should be unaffected, and the
        # globals and set names should be unchanged.

        pathFilter["paths"].setValue(
            IECore.StringVectorData(["/groupA/groupB"]))

        for path in ["/", "/groupA", "/groupA/sphere"]:
            self.assertPathHashesEqual(groupA["out"], path, encapsulate["out"],
                                       path)
            self.assertPathsEqual(groupA["out"], path, encapsulate["out"],
                                  path)

        for plugName in ["globals", "setNames"]:
            self.assertEqual(groupA["out"][plugName].hash(),
                             encapsulate["out"][plugName].hash())
            self.assertEqual(groupA["out"][plugName].getValue(),
                             encapsulate["out"][plugName].getValue())

        # And even for matched paths, the attributes, transform
        # and bound should be passed through unchanged.

        self.assertEqual(groupA["out"].attributesHash("/groupA/groupB"),
                         encapsulate["out"].attributesHash("/groupA/groupB"))
        self.assertEqual(groupA["out"].attributes("/groupA/groupB"),
                         encapsulate["out"].attributes("/groupA/groupB"))

        self.assertEqual(groupA["out"].transformHash("/groupA/groupB"),
                         encapsulate["out"].transformHash("/groupA/groupB"))
        self.assertEqual(groupA["out"].transform("/groupA/groupB"),
                         encapsulate["out"].transform("/groupA/groupB"))

        self.assertEqual(groupA["out"].boundHash("/groupA/groupB"),
                         encapsulate["out"].boundHash("/groupA/groupB"))
        self.assertEqual(groupA["out"].bound("/groupA/groupB"),
                         encapsulate["out"].bound("/groupA/groupB"))

        # But the children should all have been pruned away
        # and replaced by an appropriate Capsule.

        self.assertEqual(encapsulate["out"].childNames("/groupA/groupB"),
                         IECore.InternedStringVectorData())
        capsule = encapsulate["out"].object("/groupA/groupB")
        self.assertIsInstance(capsule, GafferScene.Capsule)
        self.assertEqual(capsule.scene(), groupA["out"])
        self.assertEqual(capsule.root(), "/groupA/groupB")
        self.assertEqual(capsule.bound(),
                         groupA["out"].bound("/groupA/groupB"))

        # And the sets should also have been pruned so they
        # don't include the objects beneath the capsule.

        self.assertEqual(encapsulate["out"].set("sphereSet").value.paths(),
                         ["/groupA/sphere"])
        self.assertEqual(encapsulate["out"].set("cubeSet").value.paths(), [])

        with six.assertRaisesRegex(
                self, Gaffer.ProcessException,
                "Encapsulate.out.childNames : Tried to access path \"/groupA/groupB/sphere\", but its ancestor has been converted to a capsule"
        ):
            encapsulate["out"].childNames("/groupA/groupB/sphere")

        with six.assertRaisesRegex(
                self, Gaffer.ProcessException,
                "Encapsulate.out.object : Tried to access path \"/groupA/groupB/sphere\", but its ancestor has been converted to a capsule"
        ):
            encapsulate["out"].object("/groupA/groupB/sphere")

        # As a double check, test that this setup works properly with Unencapsulate
        unencapsulateFilter = GafferScene.PathFilter()

        unencapsulate = GafferScene.Unencapsulate()
        unencapsulate["in"].setInput(encapsulate["out"])
        unencapsulate["filter"].setInput(unencapsulateFilter["out"])

        # We can reverse the encapsulate by unencapsulating everything
        unencapsulateFilter["paths"].setValue(IECore.StringVectorData(["..."]))
        self.assertScenesEqual(encapsulate["in"], unencapsulate["out"])

        # Or by targetting just the path that was encapsulated
        unencapsulateFilter["paths"].setValue(
            IECore.StringVectorData(["/groupA/groupB"]))
        self.assertScenesEqual(encapsulate["in"], unencapsulate["out"])

        # But if we don't target that path, the scene stays encapsulated
        unencapsulateFilter["paths"].setValue(
            IECore.StringVectorData(["/groupA/"]))
        self.assertScenesEqual(encapsulate["out"], unencapsulate["out"])
    def testCapsuleHash(self):

        sphere = GafferScene.Sphere()
        group1 = GafferScene.Group()
        group1["in"][0].setInput(sphere["out"])
        group2 = GafferScene.Group()
        group2["in"][0].setInput(group1["out"])

        pathFilter = GafferScene.PathFilter()
        pathFilter["paths"].setValue(IECore.StringVectorData(["/group/group"]))

        encapsulate = GafferScene.Encapsulate()
        encapsulate["in"].setInput(group2["out"])
        encapsulate["filter"].setInput(pathFilter["out"])

        objectHashes = set()
        capsuleHashes = set()

        def assertHashesUnique(path):

            objectHash = encapsulate["out"].objectHash(path)
            capsule = encapsulate["out"].object(path)
            self.assertIsInstance(capsule, GafferScene.Capsule)
            capsuleHash = capsule.hash()

            self.assertNotIn(objectHash, objectHashes)
            self.assertNotIn(capsuleHash, capsuleHashes)

            objectHashes.add(objectHash)
            capsuleHashes.add(capsuleHash)

        assertHashesUnique("/group/group")

        sphere["radius"].setValue(2)
        assertHashesUnique("/group/group")

        sphere["name"].setValue("bigSphere")
        assertHashesUnique("/group/group")

        sphere["transform"]["translate"]["x"].setValue(1)
        assertHashesUnique("/group/group")

        pathFilter["paths"].setValue(IECore.StringVectorData(["/group"]))
        assertHashesUnique("/group")

        encapsulate["in"].setInput(group1["out"])
        assertHashesUnique("/group")

        # Test changing the filter or globals
        group2["in"][1].setInput(group1["out"])

        options = GafferScene.CustomOptions()
        options["in"].setInput(group2["out"])

        encapsulate["in"].setInput(options["out"])
        pathFilter["paths"].setValue(IECore.StringVectorData(["/group/group"]))

        c = encapsulate["out"].object("/group/group")

        # Changing filter doesn't affect hash
        pathFilter["paths"].setValue(
            IECore.StringVectorData(["/group/group", "/group/group2"]))
        self.assertEqual(c, encapsulate["out"].object("/group/group"))

        # Changing globals shouldn't affect hash
        # \todo : But it currently does due to current issue with handling motion blur.  Change this
        # assertNotEqual to an assertEqual after fixing shutter handling for capsules
        options["options"].addChild(
            Gaffer.NameValuePlug("test", IECore.IntData(10)))
        self.assertNotEqual(c, encapsulate["out"].object("/group/group"))
Beispiel #10
0
	def test( self ) :

		# - groupA
		#    - groupB
		#       - sphere
		#       - cube
		#    - sphere

		sphere = GafferScene.Sphere()
		sphere["sets"].setValue( "sphereSet" )

		cube = GafferScene.Cube()
		cube["sets"].setValue( "cubeSet" )

		groupB = GafferScene.Group()
		groupB["in"][0].setInput( sphere["out"] )
		groupB["in"][1].setInput( sphere["out"] )
		groupB["name"].setValue( "groupB" )

		groupA = GafferScene.Group()
		groupA["in"][0].setInput( groupB["out"] )
		groupA["in"][1].setInput( sphere["out"] )
		groupA["name"].setValue( "groupA" )

		# When there is no filter attached, the node
		# should be an exact pass-through.

		encapsulate = GafferScene.Encapsulate()
		encapsulate["in"].setInput( groupA["out"] )

		self.assertSceneHashesEqual( encapsulate["out"], groupA["out"], checks = self.allSceneChecks - { "sets" } )
		self.assertScenesEqual( encapsulate["out"], groupA["out"] )

		# The same goes if there is a filter but it
		# doesn't match anything.

		pathFilter = GafferScene.PathFilter()
		encapsulate["filter"].setInput( pathFilter["out"] )

		self.assertSceneHashesEqual( encapsulate["out"], groupA["out"], checks = self.allSceneChecks - { "sets" } )
		self.assertScenesEqual( encapsulate["out"], groupA["out"] )

		# Even when the filter does match something, the
		# unmatched paths should be unaffected, and the
		# globals and set names should be unchanged.

		pathFilter["paths"].setValue( IECore.StringVectorData( [ "/groupA/groupB" ] ) )

		for path in [ "/", "/groupA", "/groupA/sphere" ] :
			self.assertPathHashesEqual( groupA["out"], path, encapsulate["out"], path )
			self.assertPathsEqual( groupA["out"], path, encapsulate["out"], path )

		for plugName in [ "globals", "setNames" ] :
			self.assertEqual( groupA["out"][plugName].hash(), encapsulate["out"][plugName].hash() )
			self.assertEqual( groupA["out"][plugName].getValue(), encapsulate["out"][plugName].getValue() )

		# And even for matched paths, the attributes, transform
		# and bound should be passed through unchanged.

		self.assertEqual( groupA["out"].attributesHash( "/groupA/groupB" ), encapsulate["out"].attributesHash( "/groupA/groupB" ) )
		self.assertEqual( groupA["out"].attributes( "/groupA/groupB" ), encapsulate["out"].attributes( "/groupA/groupB" ) )

		self.assertEqual( groupA["out"].transformHash( "/groupA/groupB" ), encapsulate["out"].transformHash( "/groupA/groupB" ) )
		self.assertEqual( groupA["out"].transform( "/groupA/groupB" ), encapsulate["out"].transform( "/groupA/groupB" ) )

		self.assertEqual( groupA["out"].boundHash( "/groupA/groupB" ), encapsulate["out"].boundHash( "/groupA/groupB" ) )
		self.assertEqual( groupA["out"].bound( "/groupA/groupB" ), encapsulate["out"].bound( "/groupA/groupB" ) )

		# But the children should all have been pruned away
		# and replaced by an appropriate Capsule.

		self.assertEqual( encapsulate["out"].childNames( "/groupA/groupB" ), IECore.InternedStringVectorData() )
		capsule = encapsulate["out"].object( "/groupA/groupB" )
		self.assertIsInstance( capsule, GafferScene.Capsule )
		self.assertEqual( capsule.scene(), groupA["out"] )
		self.assertEqual( capsule.root(), "/groupA/groupB" )
		self.assertEqual( capsule.bound(), groupA["out"].bound( "/groupA/groupB" ) )

		# And the sets should also have been pruned so they
		# don't include the objects beneath the capsule.

		self.assertEqual( encapsulate["out"].set( "sphereSet" ).value.paths(), [ "/groupA/sphere" ] )
		self.assertEqual( encapsulate["out"].set( "cubeSet" ).value.paths(), [] )