Exemple #1
0
	def testMotion( self ) :

		p1 = IECoreScene.PointsPrimitive( IECore.V3fVectorData( [ imath.V3f( 10 ) ] * 10 ) )
		p1["width"] = IECoreScene.PrimitiveVariable(
			IECoreScene.PrimitiveVariable.Interpolation.Vertex,
			IECore.FloatVectorData( [ 1 ] * 10 ),
		)

		p2 = IECoreScene.PointsPrimitive( IECore.V3fVectorData( [ imath.V3f( 20 ) ] * 10 ) )
		p2["width"] = IECoreScene.PrimitiveVariable(
			IECoreScene.PrimitiveVariable.Interpolation.Vertex,
			IECore.FloatVectorData( [ 2 ] * 10 ),
		)

		with IECoreArnold.UniverseBlock( writable = True ) :

			n = IECoreArnold.NodeAlgo.convert( [ p1, p2 ], -0.25, 0.25, "testPoints" )

			a = arnold.AiNodeGetArray( n, "points" )
			self.assertEqual( arnold.AiArrayGetNumElements( a.contents ), 10 )
			self.assertEqual( arnold.AiArrayGetNumKeys( a.contents ), 2 )

			r = arnold.AiNodeGetArray( n, "radius" )
			self.assertEqual( arnold.AiArrayGetNumElements( r.contents ), 10 )
			self.assertEqual( arnold.AiArrayGetNumKeys( r.contents ), 2 )

			for i in range( 0, 10 ) :
				self.assertEqual( arnold.AiArrayGetVec( a, i ), arnold.AtVector( 10 ) )
				self.assertEqual( arnold.AiArrayGetFlt( r, i ), 0.5 )
			for i in range( 11, 20 ) :
				self.assertEqual( arnold.AiArrayGetVec( a, i ), arnold.AtVector( 20 ) )
				self.assertEqual( arnold.AiArrayGetFlt( r, i ), 1 )

			self.assertEqual( arnold.AiNodeGetFlt( n, "motion_start" ), -0.25 )
			self.assertEqual( arnold.AiNodeGetFlt( n, "motion_end" ), 0.25 )
Exemple #2
0
    def testMotion(self):

        c1 = IECoreScene.CurvesPrimitive(IECore.IntVectorData([4]))
        c2 = IECoreScene.CurvesPrimitive(IECore.IntVectorData([4]))

        c1["P"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.Vertex,
            IECore.V3fVectorData([imath.V3f(1)] * 4),
        )

        c2["P"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.Vertex,
            IECore.V3fVectorData([imath.V3f(2)] * 4),
        )

        with IECoreArnold.UniverseBlock(writable=True) as universe:

            n = IECoreArnold.NodeAlgo.convert([c1, c2], -0.25, 0.25, universe,
                                              "testCurve")

            a = arnold.AiNodeGetArray(n, "points")
            self.assertEqual(arnold.AiArrayGetNumElements(a.contents), 4)
            self.assertEqual(arnold.AiArrayGetNumKeys(a.contents), 2)

            for i in range(0, 4):
                self.assertEqual(arnold.AiArrayGetVec(a, i),
                                 arnold.AtVector(1))
            for i in range(4, 8):
                self.assertEqual(arnold.AiArrayGetVec(a, i),
                                 arnold.AtVector(2))

            self.assertEqual(arnold.AiNodeGetFlt(n, "motion_start"), -0.25)
            self.assertEqual(arnold.AiNodeGetFlt(n, "motion_end"), 0.25)
    def testNormals(self):

        m = IECoreScene.MeshPrimitive.createPlane(
            imath.Box2f(imath.V2f(-0.9), imath.V2f(0.9)))
        m["N"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.Vertex,
            IECore.V3fVectorData([
                imath.V3f(1, 0, 0),
                imath.V3f(1, 0, 0),
                imath.V3f(1, 0, 0),
                imath.V3f(1, 0, 0)
            ]))

        mFaceVaryingIndexed = IECoreScene.MeshPrimitive.createBox(
            imath.Box3f(imath.V3f(-0.9), imath.V3f(0.9)))

        mVertexIndexed = IECoreScene.MeshPrimitive.createPlane(
            imath.Box2f(imath.V2f(-0.9), imath.V2f(0.9)), imath.V2i(3))
        mVertexIndexed["N"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.Vertex,
            IECore.V3fVectorData([imath.V3f(1, 0, 0),
                                  imath.V3f(-1, 0, 0)]),
            IECore.IntVectorData([0] * 8 + [1] * 8))

        with IECoreArnold.UniverseBlock(writable=True) as universe:

            n = IECoreArnold.NodeAlgo.convert(m, universe, "testMesh")

            normals = arnold.AiNodeGetArray(n, "nlist")
            self.assertEqual(arnold.AiArrayGetNumElements(normals.contents), 4)

            for i in range(0, 4):
                self.assertEqual(arnold.AiArrayGetVec(normals, i),
                                 arnold.AtVector(1, 0, 0))

            n = IECoreArnold.NodeAlgo.convert(mFaceVaryingIndexed, universe,
                                              "testMesh2")
            normals = arnold.AiNodeGetArray(n, "nlist")
            normalIndices = arnold.AiNodeGetArray(n, "nidxs")

            refNormals = [(0, 0, -1), (1, 0, 0), (0, 0, 1), (-1, 0, 0),
                          (0, 1, 0), (0, -1, 0)]
            for i in range(0, 24):
                self.assertEqual(
                    arnold.AiArrayGetVec(
                        normals, arnold.AiArrayGetInt(normalIndices, i)),
                    arnold.AtVector(*refNormals[i // 4]))

            n = IECoreArnold.NodeAlgo.convert(mVertexIndexed, universe,
                                              "testMesh3")
            normals = arnold.AiNodeGetArray(n, "nlist")
            normalIndices = arnold.AiNodeGetArray(n, "nidxs")
            for i in range(0, 36):
                s = [0, (i // 2) % 2, 1][i // 12]
                self.assertEqual(
                    arnold.AiArrayGetVec(
                        normals, arnold.AiArrayGetInt(normalIndices, i)),
                    arnold.AtVector(-1 if s else 1, 0, 0))
Exemple #4
0
    def testNPrimitiveVariable(self):

        c = IECore.CurvesPrimitive(IECore.IntVectorData([4]),
                                   IECore.CubicBasisf.catmullRom())
        c["P"] = IECore.PrimitiveVariable(
            IECore.PrimitiveVariable.Interpolation.Vertex,
            IECore.V3fVectorData([IECore.V3f(x, 0, 0) for x in range(0, 4)]))

        with IECoreArnold.UniverseBlock(writable=True):

            # No N - should be a ribbon

            n = IECoreArnold.NodeAlgo.convert(c)
            self.assertEqual(arnold.AiNodeGetStr(n, "mode"), "ribbon")
            self.assertEqual(
                arnold.AiNodeGetArray(n, "orientations").contents.nelements, 0)

            # N - should be oriented

            c["N"] = IECore.PrimitiveVariable(
                IECore.PrimitiveVariable.Interpolation.Vertex,
                IECore.V3fVectorData([
                    IECore.V3f(0, math.sin(x), math.cos(x))
                    for x in range(0, 4)
                ]))

            n = IECoreArnold.NodeAlgo.convert(c)
            self.assertEqual(arnold.AiNodeGetStr(n, "mode"), "oriented")
            orientations = arnold.AiNodeGetArray(n, "orientations")
            self.assertEqual(orientations.contents.nelements, 4)

            for i in range(0, 4):
                self.assertEqual(arnold.AiArrayGetVec(orientations, i),
                                 arnold.AtVector(0, math.sin(i), math.cos(i)))

            # Motion blurred N - should be oriented and deforming

            c2 = c.copy()
            c2["N"] = IECore.PrimitiveVariable(
                IECore.PrimitiveVariable.Interpolation.Vertex,
                IECore.V3fVectorData([
                    IECore.V3f(0, math.sin(x + 0.2), math.cos(x + 0.2))
                    for x in range(0, 4)
                ]))

            n = IECoreArnold.NodeAlgo.convert([c, c2], [0.0, 1.0])
            self.assertEqual(arnold.AiNodeGetStr(n, "mode"), "oriented")

            orientations = arnold.AiNodeGetArray(n, "orientations")
            self.assertEqual(orientations.contents.nelements, 4)
            self.assertEqual(orientations.contents.nkeys, 2)

            for i in range(0, 4):
                self.assertEqual(arnold.AiArrayGetVec(orientations, i),
                                 arnold.AtVector(0, math.sin(i), math.cos(i)))
                self.assertEqual(
                    arnold.AiArrayGetVec(orientations, i + 4),
                    arnold.AtVector(0, math.sin(i + 0.2), math.cos(i + 0.2)))
def __aiMetadataGetVec(nodeEntry, paramName, name, defaultValue=None):

    value = arnold.AtVector()
    if arnold.AiMetaDataGetVec(nodeEntry, paramName, name, value):
        return imath.V3f(value.x, value.y, value.z)

    return defaultValue
Exemple #6
0
	def testPrimitiveVariables( self ) :

		s = IECore.SpherePrimitive()
		s["v"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, IECore.V3f( 1, 2, 3 ) )
		s["c"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, IECore.Color3f( 1, 2, 3 ) )
		s["s"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, "test" )
		s["i"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, 11 )
		s["b"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, True )
		s["f"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, 2.5 )
		s["m"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, IECore.M44f( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) )

		with IECoreArnold.UniverseBlock( writable = True ) :

			n = IECoreArnold.NodeAlgo.convert( s, "testSphere" )
			self.assertEqual( arnold.AiNodeGetVec( n, "v" ), arnold.AtVector( 1, 2, 3 ) )
			self.assertEqual( arnold.AiNodeGetRGB( n, "c" ), arnold.AtRGB( 1, 2, 3 ) )
			self.assertEqual( arnold.AiNodeGetStr( n, "s" ), "test" )
			self.assertEqual( arnold.AiNodeGetInt( n, "i" ), 11 )
			self.assertEqual( arnold.AiNodeGetBool( n, "b" ), True )
			self.assertEqual( arnold.AiNodeGetFlt( n, "f" ), 2.5 )

			m = arnold.AiNodeGetMatrix( n, "m" )
			self.assertEqual(
				[ list( i ) for i in m.data ],
				[ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16] ],
			)
	def testVectorIntData( self ) :

		with IECoreArnold.UniverseBlock( writable = True ) :

			n = arnold.AiNode( "standard_surface" )

			IECoreArnold.ParameterAlgo.setParameter( n, "customV2i", IECore.V2iData( IECore.V2i( 3, 4 ) ) )
			self.assertEqual( arnold.AiNodeGetVec2( n, "customV2i" ), arnold.AtVector2( 3, 4 ) )

			IECoreArnold.ParameterAlgo.setParameter( n, "customV3i", IECore.V3iData( IECore.V3i( 3, 4, 5 ) ) )
			self.assertEqual( arnold.AiNodeGetVec( n, "customV3i" ), arnold.AtVector( 3, 4, 5 ) )
Exemple #8
0
    def testBlindData(self):

        flat = IECoreScene.Shader("flat")
        flat.blindData().update({
            "user:testInt":
            IECore.IntData(1),
            "user:testFloat":
            IECore.FloatData(2.5),
            "user:testV3f":
            IECore.V3fData(imath.V3f(1, 2, 3)),
            "user:testColor3f":
            IECore.Color3fData(imath.Color3f(4, 5, 6)),
            "user:testString":
            IECore.StringData("we're all doomed"),
        })

        network = IECoreScene.ShaderNetwork(shaders={
            "noiseHandle":
            IECoreScene.Shader("noise"),
            "flatHandle":
            flat,
        },
                                            connections=[
                                                (("noiseHandle", ""),
                                                 ("flatHandle", "color")),
                                            ],
                                            output="flatHandle")

        with IECoreArnold.UniverseBlock(writable=True) as universe:

            nodes = IECoreArnoldPreview.ShaderNetworkAlgo.convert(
                network, universe, "test")

            self.assertEqual(len(nodes), 2)
            self.assertEqual(
                arnold.AiNodeEntryGetName(arnold.AiNodeGetNodeEntry(nodes[0])),
                "noise")
            self.assertEqual(
                arnold.AiNodeEntryGetName(arnold.AiNodeGetNodeEntry(nodes[1])),
                "flat")

            self.assertEqual(arnold.AiNodeGetName(nodes[0]),
                             "test:noiseHandle")
            self.assertEqual(arnold.AiNodeGetName(nodes[1]), "test")

            self.assertEqual(arnold.AiNodeGetInt(nodes[1], "user:testInt"), 1)
            self.assertEqual(arnold.AiNodeGetFlt(nodes[1], "user:testFloat"),
                             2.5)
            self.assertEqual(arnold.AiNodeGetVec(nodes[1], "user:testV3f"),
                             arnold.AtVector(1, 2, 3))
            self.assertEqual(arnold.AiNodeGetRGB(nodes[1], "user:testColor3f"),
                             arnold.AtRGB(4, 5, 6))
            self.assertEqual(arnold.AiNodeGetStr(nodes[1], "user:testString"),
                             "we're all doomed")
Exemple #9
0
    def testNormals(self):

        m = IECoreScene.MeshPrimitive.createPlane(
            imath.Box2f(imath.V2f(-0.9), imath.V2f(0.9)))
        m["N"] = IECoreScene.PrimitiveVariable(
            IECoreScene.PrimitiveVariable.Interpolation.Vertex,
            IECore.V3fVectorData([
                imath.V3f(1, 0, 0),
                imath.V3f(1, 0, 0),
                imath.V3f(1, 0, 0),
                imath.V3f(1, 0, 0)
            ]))

        with IECoreArnold.UniverseBlock(writable=True):

            n = IECoreArnold.NodeAlgo.convert(m, "testMesh")

            normals = arnold.AiNodeGetArray(n, "nlist")
            self.assertEqual(arnold.AiArrayGetNumElements(normals.contents), 4)

            for i in range(0, 4):
                self.assertEqual(arnold.AiArrayGetVec(normals, i),
                                 arnold.AtVector(1, 0, 0))
Exemple #10
0
	def testTransformMotion( self ) :

		s = Gaffer.ScriptNode()

		s["plane"] = GafferScene.Plane()
		s["sphere"] = GafferScene.Sphere()
		s["group"] = GafferScene.Group()
		s["group"]["in"][0].setInput( s["plane"]["out"] )
		s["group"]["in"][1].setInput( s["sphere"]["out"] )

		s["expression"] = Gaffer.Expression()
		s["expression"].setExpression(
			inspect.cleandoc(
				"""
				parent["plane"]["transform"]["translate"]["x"] = context.getFrame()
				parent["sphere"]["transform"]["translate"]["y"] = context.getFrame() * 2
				parent["group"]["transform"]["translate"]["z"] = context.getFrame() - 1
				"""
			)
		)

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

		s["attributes"] = GafferScene.StandardAttributes()
		s["attributes"]["in"].setInput( s["group"]["out"] )
		s["attributes"]["filter"].setInput( s["planeFilter"]["out"] )
		s["attributes"]["attributes"]["transformBlur"]["enabled"].setValue( True )
		s["attributes"]["attributes"]["transformBlur"]["value"].setValue( False )

		s["options"] = GafferScene.StandardOptions()
		s["options"]["in"].setInput( s["attributes"]["out"] )
		s["options"]["options"]["shutter"]["enabled"].setValue( True )
		s["options"]["options"]["transformBlur"]["enabled"].setValue( True )

		s["render"] = GafferArnold.ArnoldRender()
		s["render"]["in"].setInput( s["options"]["out"] )
		s["render"]["mode"].setValue( s["render"].Mode.SceneDescriptionMode )
		s["render"]["fileName"].setValue( self.temporaryDirectory() + "/test.ass" )

		# No motion blur

		s["options"]["options"]["transformBlur"]["value"].setValue( False )
		s["render"]["task"].execute()

		with IECoreArnold.UniverseBlock( writable = True ) :

			arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" )

			camera = arnold.AiNodeLookUpByName( "gaffer:defaultCamera" )
			sphere = arnold.AiNodeLookUpByName( "/group/sphere" )
			sphereMotionStart = arnold.AiNodeGetFlt( sphere, "motion_start" )
			sphereMotionEnd = arnold.AiNodeGetFlt( sphere, "motion_end" )
			sphereMatrix = arnold.AiNodeGetMatrix( sphere, "matrix" )

			plane = arnold.AiNodeLookUpByName( "/group/plane" )
			planeMotionStart = arnold.AiNodeGetFlt( plane, "motion_start" )
			planeMotionEnd = arnold.AiNodeGetFlt( plane, "motion_end" )
			planeMatrix = arnold.AiNodeGetMatrix( plane, "matrix" )

			# Motion parameters should be left at default
			self.assertEqual( sphereMotionStart, 0 )
			self.assertEqual( sphereMotionEnd, 1 )
			self.assertEqual( planeMotionStart, 0 )
			self.assertEqual( planeMotionEnd, 1 )

			expectedSphereMatrix = arnold.AiM4Translation( arnold.AtVector( 0, 2, 0 ) )

			expectedPlaneMatrix = arnold.AiM4Translation( arnold.AtVector( 1, 0, 0 ) )

			self.assertEqual( self.__m44f( sphereMatrix ), self.__m44f( expectedSphereMatrix ) )
			self.assertEqual( self.__m44f( planeMatrix ), self.__m44f( expectedPlaneMatrix ) )

			self.assertEqual( arnold.AiNodeGetFlt( camera, "shutter_start" ), 1 )
			self.assertEqual( arnold.AiNodeGetFlt( camera, "shutter_end" ), 1 )

		# Motion blur

		s["options"]["options"]["transformBlur"]["value"].setValue( True )
		s["render"]["task"].execute()

		with IECoreArnold.UniverseBlock( writable = True ) :

			arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" )

			camera = arnold.AiNodeLookUpByName( "gaffer:defaultCamera" )
			sphere = arnold.AiNodeLookUpByName( "/group/sphere" )
			sphereMotionStart = arnold.AiNodeGetFlt( sphere, "motion_start" )
			sphereMotionEnd = arnold.AiNodeGetFlt( sphere, "motion_end" )
			sphereMatrices = arnold.AiNodeGetArray( sphere, "matrix" )

			plane = arnold.AiNodeLookUpByName( "/group/plane" )
			planeMotionStart = arnold.AiNodeGetFlt( plane, "motion_start" )
			planeMotionEnd = arnold.AiNodeGetFlt( plane, "motion_end" )
			planeMatrices = arnold.AiNodeGetArray( plane, "matrix" )

			self.assertEqual( sphereMotionStart, 0.75 )
			self.assertEqual( sphereMotionEnd, 1.25 )
			self.assertEqual( arnold.AiArrayGetNumElements( sphereMatrices.contents ), 1 )
			self.assertEqual( arnold.AiArrayGetNumKeys( sphereMatrices.contents ), 2 )

			self.assertEqual( planeMotionStart, 0.75 )
			self.assertEqual( planeMotionEnd, 1.25 )
			self.assertEqual( arnold.AiArrayGetNumElements( planeMatrices.contents ), 1 )
			self.assertEqual( arnold.AiArrayGetNumKeys( planeMatrices.contents ), 2 )

			for i in range( 0, 2 ) :

				frame = 0.75 + 0.5 * i
				sphereMatrix = arnold.AiArrayGetMtx( sphereMatrices, i )

				expectedSphereMatrix = arnold.AiM4Translation( arnold.AtVector( 0, frame * 2, frame - 1 ) )

				planeMatrix = arnold.AiArrayGetMtx( planeMatrices, i )

				expectedPlaneMatrix = arnold.AiM4Translation( arnold.AtVector( 1, 0, frame - 1 ) )

				self.assertEqual( self.__m44f( sphereMatrix ), self.__m44f( expectedSphereMatrix ) )
				self.assertEqual( self.__m44f( planeMatrix ), self.__m44f( expectedPlaneMatrix ) )

			self.assertEqual( arnold.AiNodeGetFlt( camera, "shutter_start" ), 0.75 )
			self.assertEqual( arnold.AiNodeGetFlt( camera, "shutter_end" ), 1.25 )

		# Motion blur on, but sampleMotion off

		s["options"]["options"]["sampleMotion"]["enabled"].setValue( True )
		s["options"]["options"]["sampleMotion"]["value"].setValue( False )
		s["render"]["task"].execute()

		with IECoreArnold.UniverseBlock( writable = True ) :

			arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" )

			camera = arnold.AiNodeLookUpByName( "gaffer:defaultCamera" )
			sphere = arnold.AiNodeLookUpByName( "/group/sphere" )
			sphereMotionStart = arnold.AiNodeGetFlt( sphere, "motion_start" )
			sphereMotionEnd = arnold.AiNodeGetFlt( sphere, "motion_end" )
			sphereMatrices = arnold.AiNodeGetArray( sphere, "matrix" )

			plane = arnold.AiNodeLookUpByName( "/group/plane" )
			planeMotionStart = arnold.AiNodeGetFlt( plane, "motion_start" )
			planeMotionEnd = arnold.AiNodeGetFlt( plane, "motion_end" )
			planeMatrices = arnold.AiNodeGetArray( plane, "matrix" )

			self.assertEqual( sphereMotionStart, 0.75 )
			self.assertEqual( sphereMotionEnd, 1.25 )
			self.assertEqual( arnold.AiArrayGetNumElements( sphereMatrices.contents ), 1 )
			self.assertEqual( arnold.AiArrayGetNumKeys( sphereMatrices.contents ), 2 )

			self.assertEqual( planeMotionStart, 0.75 )
			self.assertEqual( planeMotionEnd, 1.25 )
			self.assertEqual( arnold.AiArrayGetNumElements( planeMatrices.contents ), 1 )
			self.assertEqual( arnold.AiArrayGetNumKeys( planeMatrices.contents ), 2 )

			for i in range( 0, 2 ) :

				frame = 0.75 + 0.5 * i

				sphereMatrix = arnold.AiArrayGetMtx( sphereMatrices, i )

				expectedSphereMatrix = arnold.AiM4Translation( arnold.AtVector( 0, frame * 2, frame - 1 ) )

				planeMatrix = arnold.AiArrayGetMtx( planeMatrices, i )

				expectedPlaneMatrix = arnold.AiM4Translation( arnold.AtVector( 1, 0, frame - 1 ) )

				self.assertEqual( self.__m44f( sphereMatrix ), self.__m44f( expectedSphereMatrix ) )
				self.assertEqual( self.__m44f( planeMatrix ), self.__m44f( expectedPlaneMatrix ) )

			self.assertEqual( arnold.AiNodeGetFlt( camera, "shutter_start" ), 0.75 )
			self.assertEqual( arnold.AiNodeGetFlt( camera, "shutter_end" ), 0.75 )
    def testTransformMotion(self):

        s = Gaffer.ScriptNode()

        s["plane"] = GafferScene.Plane()
        s["sphere"] = GafferScene.Sphere()
        s["group"] = GafferScene.Group()
        s["group"]["in"][0].setInput(s["plane"]["out"])
        s["group"]["in"][1].setInput(s["sphere"]["out"])

        s["expression"] = Gaffer.Expression()
        s["expression"].setExpression(
            inspect.cleandoc("""
				parent["plane"]["transform"]["translate"]["x"] = context.getFrame()
				parent["sphere"]["transform"]["translate"]["y"] = context.getFrame() * 2
				parent["group"]["transform"]["translate"]["z"] = context.getFrame() - 1
				"""))

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

        s["attributes"] = GafferScene.StandardAttributes()
        s["attributes"]["in"].setInput(s["group"]["out"])
        s["attributes"]["filter"].setInput(s["planeFilter"]["out"])
        s["attributes"]["attributes"]["transformBlur"]["enabled"].setValue(
            True)
        s["attributes"]["attributes"]["transformBlur"]["value"].setValue(False)

        s["options"] = GafferScene.StandardOptions()
        s["options"]["in"].setInput(s["attributes"]["out"])
        s["options"]["options"]["transformBlur"]["enabled"].setValue(True)

        s["render"] = GafferArnold.ArnoldRender()
        s["render"]["in"].setInput(s["options"]["out"])
        s["render"]["mode"].setValue(s["render"].Mode.SceneDescriptionMode)
        s["render"]["fileName"].setValue(self.temporaryDirectory() +
                                         "/test.ass")

        # No motion blur

        s["options"]["options"]["transformBlur"]["value"].setValue(False)
        s["render"]["task"].execute()

        with IECoreArnold.UniverseBlock(writable=True):

            arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass")

            sphere = arnold.AiNodeLookUpByName("/group/sphere")
            sphereTimes = arnold.AiNodeGetArray(sphere,
                                                "transform_time_samples")
            sphereMatrix = arnold.AtMatrix()
            arnold.AiNodeGetMatrix(sphere, "matrix", sphereMatrix)

            plane = arnold.AiNodeLookUpByName("/group/plane")
            planeTimes = arnold.AiNodeGetArray(plane, "transform_time_samples")
            planeMatrix = arnold.AtMatrix()
            arnold.AiNodeGetMatrix(plane, "matrix", planeMatrix)

            expectedSphereMatrix = arnold.AtMatrix()
            arnold.AiM4Translation(expectedSphereMatrix,
                                   arnold.AtVector(0, 2, 0))

            expectedPlaneMatrix = arnold.AtMatrix()
            arnold.AiM4Translation(expectedPlaneMatrix,
                                   arnold.AtVector(1, 0, 0))

            self.__assertStructsEqual(sphereMatrix, expectedSphereMatrix)
            self.__assertStructsEqual(planeMatrix, expectedPlaneMatrix)

        # Motion blur

        s["options"]["options"]["transformBlur"]["value"].setValue(True)
        s["render"]["task"].execute()

        with IECoreArnold.UniverseBlock(writable=True):

            arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass")

            sphere = arnold.AiNodeLookUpByName("/group/sphere")
            sphereTimes = arnold.AiNodeGetArray(sphere,
                                                "transform_time_samples")
            sphereMatrices = arnold.AiNodeGetArray(sphere, "matrix")

            plane = arnold.AiNodeLookUpByName("/group/plane")
            planeTimes = arnold.AiNodeGetArray(plane, "transform_time_samples")
            planeMatrices = arnold.AiNodeGetArray(plane, "matrix")

            self.assertEqual(sphereTimes.contents.nelements, 2)
            self.assertEqual(sphereTimes.contents.nkeys, 1)
            self.assertEqual(sphereMatrices.contents.nelements, 1)
            self.assertEqual(sphereMatrices.contents.nkeys, 2)

            self.assertEqual(planeTimes.contents.nelements, 2)
            self.assertEqual(planeTimes.contents.nkeys, 1)
            self.assertEqual(planeMatrices.contents.nelements, 1)
            self.assertEqual(planeMatrices.contents.nkeys, 2)

            for i in range(0, 2):

                frame = 0.75 + 0.5 * i
                self.assertEqual(arnold.AiArrayGetFlt(sphereTimes, i), frame)
                self.assertEqual(arnold.AiArrayGetFlt(planeTimes, i), frame)

                sphereMatrix = arnold.AtMatrix()
                arnold.AiArrayGetMtx(sphereMatrices, i, sphereMatrix)

                expectedSphereMatrix = arnold.AtMatrix()
                arnold.AiM4Translation(
                    expectedSphereMatrix,
                    arnold.AtVector(0, frame * 2, frame - 1))

                planeMatrix = arnold.AtMatrix()
                arnold.AiArrayGetMtx(planeMatrices, i, planeMatrix)

                expectedPlaneMatrix = arnold.AtMatrix()
                arnold.AiM4Translation(expectedPlaneMatrix,
                                       arnold.AtVector(1, 0, frame - 1))

                self.__assertStructsEqual(sphereMatrix, expectedSphereMatrix)
                self.__assertStructsEqual(planeMatrix, expectedPlaneMatrix)