def testCropWindow(self): r = GafferScene.Private.IECoreScenePreview.Renderer.create( "IECoreArnold::Renderer", GafferScene.Private.IECoreScenePreview. Renderer.RenderType.SceneDescription, self.temporaryDirectory() + "/test.ass") r.camera( "testCamera", IECore.Camera( parameters={ "resolution": IECore.V2i(2000, 1000), "cropWindow": IECore.Box2f(IECore.V2f(0), IECore.V2f(1, 0.75)), })) r.option("camera", IECore.StringData("testCamera")) r.render() del r with IECoreArnold.UniverseBlock(): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") options = arnold.AiUniverseGetOptions() self.assertEqual(arnold.AiNodeGetInt(options, "xres"), 2000) self.assertEqual(arnold.AiNodeGetInt(options, "yres"), 1000) self.assertEqual(arnold.AiNodeGetInt(options, "region_min_x"), 0) self.assertEqual(arnold.AiNodeGetInt(options, "region_min_y"), 0) self.assertEqual(arnold.AiNodeGetInt(options, "region_max_x"), 1999) self.assertEqual(arnold.AiNodeGetInt(options, "region_max_y"), 749)
def testLightFilters(self): s = Gaffer.ScriptNode() s["lightFilter"] = GafferArnold.ArnoldLightFilter() s["lightFilter"].loadShader("light_blocker") s["attributes"] = GafferScene.StandardAttributes() s["attributes"]["in"].setInput(s["lightFilter"]["out"]) s["attributes"]["attributes"]["filteredLights"]["enabled"].setValue( True) s["attributes"]["attributes"]["filteredLights"]["value"].setValue( "defaultLights") s["light"] = GafferArnold.ArnoldLight() s["light"].loadShader("point_light") s["gobo"] = GafferArnold.ArnoldShader() s["gobo"].loadShader("gobo") s["assignment"] = GafferScene.ShaderAssignment() s["assignment"]["in"].setInput(s["light"]["out"]) s["assignment"]["shader"].setInput(s["gobo"]["out"]) s["group"] = GafferScene.Group() s["group"]["in"][0].setInput(s["attributes"]["out"]) s["group"]["in"][1].setInput(s["assignment"]["out"]) s["render"] = GafferArnold.ArnoldRender() s["render"]["in"].setInput(s["group"]["out"]) s["render"]["mode"].setValue(s["render"].Mode.SceneDescriptionMode) s["render"]["fileName"].setValue(self.temporaryDirectory() + "/test.ass") s["render"]["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") light = arnold.AiNodeLookUpByName("light:/group/light") linkedFilters = arnold.AiNodeGetArray(light, "filters") numFilters = arnold.AiArrayGetNumElements(linkedFilters.contents) self.assertEqual(numFilters, 2) linkedFilter = arnold.cast(arnold.AiArrayGetPtr(linkedFilters, 0), arnold.POINTER(arnold.AtNode)) linkedGobo = arnold.cast(arnold.AiArrayGetPtr(linkedFilters, 1), arnold.POINTER(arnold.AtNode)) self.assertEqual(arnold.AiNodeGetName(linkedFilter), "lightFilter:/group/lightFilter") self.assertEqual( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry(linkedFilter)), "light_blocker") self.assertEqual( arnold.AiNodeEntryGetName( arnold.AiNodeGetNodeEntry(linkedGobo)), "gobo")
def testAdaptors( self ) : sphere = GafferScene.Sphere() def a() : result = GafferArnold.ArnoldAttributes() result["attributes"]["matte"]["enabled"].setValue( True ) result["attributes"]["matte"]["value"].setValue( True ) return result GafferScene.registerAdaptor( "Test", a ) sphere = GafferScene.Sphere() render = GafferArnold.ArnoldRender() render["in"].setInput( sphere["out"] ) render["mode"].setValue( render.Mode.SceneDescriptionMode ) render["fileName"].setValue( self.temporaryDirectory() + "/test.ass" ) render["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) node = arnold.AiNodeLookUpByName( "/sphere" ) self.assertEqual( arnold.AiNodeGetBool( node, "matte" ), True )
def testSharedLightAttributes(self): r = GafferScene.Private.IECoreScenePreview.Renderer.create( "IECoreArnold::Renderer", GafferScene.Private.IECoreScenePreview. Renderer.RenderType.SceneDescription, self.temporaryDirectory() + "/test.ass") lightShader = IECore.ObjectVector([ IECore.Shader("point_light", "ai:light"), ]) lightAttributes = r.attributes( IECore.CompoundObject({"ai:light": lightShader})) o = r.light("testLight1", None) o.attributes(lightAttributes) o = r.light("testLight2", None) o.attributes(lightAttributes) del o, lightAttributes r.render() del r with IECoreArnold.UniverseBlock(): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") lights = self.__allNodes(type=arnold.AI_NODE_LIGHT) self.assertEqual(len(lights), 2) self.assertEqual(set([arnold.AiNodeGetName(l) for l in lights]), {"testLight1", "testLight2"})
def testFrameAndAASeed( self ) : options = GafferArnold.ArnoldOptions() render = GafferArnold.ArnoldRender() render["in"].setInput( options["out"] ) render["mode"].setValue( render.Mode.SceneDescriptionMode ) render["fileName"].setValue( self.temporaryDirectory() + "/test.ass" ) for frame in ( 1, 2, 2.8, 3.2 ) : for seed in ( None, 3, 4 ) : with Gaffer.Context() as c : c.setFrame( frame ) options["options"]["aaSeed"]["enabled"].setValue( seed is not None ) options["options"]["aaSeed"]["value"].setValue( seed or 1 ) render["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) self.assertEqual( arnold.AiNodeGetInt( arnold.AiUniverseGetOptions(), "AA_seed" ), seed or round( frame ) )
def testShaderGarbageCollection(self): r = GafferScene.Private.IECoreScenePreview.Renderer.create( "IECoreArnold::Renderer", GafferScene.Private.IECoreScenePreview. Renderer.RenderType.SceneDescription, self.temporaryDirectory() + "/test.ass") o = r.object( "testPlane", IECore.MeshPrimitive.createPlane( IECore.Box2f(IECore.V2f(-1), IECore.V2f(1)))) # Replace the shader a few times. for shader in ("utility", "flat", "standard"): a = IECore.CompoundObject({ "ai:surface": IECore.ObjectVector([IECore.Shader(shader)]), }) o.attributes(r.attributes(a)) del o, a r.render() del r with IECoreArnold.UniverseBlock(): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") # We only want one shader to have been saved, because only one was genuinely used. self.assertEqual(len(self.__allNodes(type=arnold.AI_NODE_SHADER)), 1)
def testShaderReuse(self): r = GafferScene.Private.IECoreScenePreview.Renderer.create( "IECoreArnold::Renderer", GafferScene.Private.IECoreScenePreview. Renderer.RenderType.SceneDescription, self.temporaryDirectory() + "/test.ass") for i in range(0, 10): a = IECore.CompoundObject({ "ai:surface": IECore.ObjectVector([IECore.Shader("flat")]), }) o = r.object( "testPlane", IECore.MeshPrimitive.createPlane( IECore.Box2f(IECore.V2f(-1), IECore.V2f(1)))) # We keep specifying the same shader, but we'd like the renderer # to be frugal and reuse a single arnold shader on the other side. o.attributes(r.attributes(a)) del o r.render() del r with IECoreArnold.UniverseBlock(): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") self.assertEqual(len(self.__allNodes(type=arnold.AI_NODE_SHADER)), 1)
def testResolution(self): s = Gaffer.ScriptNode() s["camera"] = GafferScene.Camera() s["options"] = GafferScene.StandardOptions() s["options"]["in"].setInput(s["camera"]["out"]) s["options"]["options"]["renderResolution"]["enabled"].setValue(True) s["options"]["options"]["renderResolution"]["value"].setValue( imath.V2i(200, 100)) s["options"]["options"]["resolutionMultiplier"]["enabled"].setValue( True) s["options"]["options"]["resolutionMultiplier"]["value"].setValue(2) 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") # Default camera should have the right resolution. s["render"]["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") options = arnold.AiUniverseGetOptions() self.assertEqual(arnold.AiNodeGetInt(options, "xres"), 400) self.assertEqual(arnold.AiNodeGetInt(options, "yres"), 200) # As should a camera picked from the scene. s["options"]["options"]["renderCamera"]["enabled"].setValue(True) s["options"]["options"]["renderCamera"]["value"].setValue("/camera") s["render"]["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") options = arnold.AiUniverseGetOptions() self.assertEqual(arnold.AiNodeGetInt(options, "xres"), 400) self.assertEqual(arnold.AiNodeGetInt(options, "yres"), 200)
def testLightFiltersMany(self): # \todo: this can easily be turned into a performance test s = Gaffer.ScriptNode() s["lightFilter"] = GafferArnold.ArnoldLightFilter() s["lightFilter"].loadShader("light_blocker") s["lightFilter"]["filteredLights"].setValue("defaultLights") s["planeFilters"] = GafferScene.Plane("Plane") s["planeFilters"]["divisions"].setValue(imath.V2i(9)) s["instancerFilters"] = GafferScene.Instancer("Instancer") s["instancerFilters"]["in"].setInput(s["planeFilters"]["out"]) s["instancerFilters"]["instances"].setInput(s["lightFilter"]["out"]) s["instancerFilters"]["parent"].setValue("/plane") s["light"] = GafferArnold.ArnoldLight() s["light"].loadShader("point_light") s["planeLights"] = GafferScene.Plane("Plane") s["planeLights"]["divisions"].setValue(imath.V2i(9)) s["instancerLights"] = GafferScene.Instancer("Instancer") s["instancerLights"]["in"].setInput(s["planeLights"]["out"]) s["instancerLights"]["instances"].setInput(s["light"]["out"]) s["instancerLights"]["parent"].setValue("/plane") s["group"] = GafferScene.Group("Group") s["group"]["in"][0].setInput(s["instancerFilters"]["out"]) s["group"]["in"][1].setInput(s["instancerLights"]["out"]) s["render"] = GafferArnold.ArnoldRender() s["render"]["in"].setInput(s["group"]["out"]) s["render"]["mode"].setValue(s["render"].Mode.SceneDescriptionMode) s["render"]["fileName"].setValue(self.temporaryDirectory() + "/testMany.ass") s["render"]["task"].execute() with IECoreArnold.UniverseBlock(writable=True): foo = self.temporaryDirectory() + "/testMany.ass" print foo arnold.AiASSLoad(foo) for i in range(100): light = arnold.AiNodeLookUpByName( "light:/group/plane1/instances/light/%s" % i) linkedFilters = arnold.AiNodeGetArray(light, "filters") numFilters = arnold.AiArrayGetNumElements( linkedFilters.contents) self.assertEqual(numFilters, 100)
def render_ass(ass, remove_ass=False): imagefilename = None ai.AiBegin() ai.AiLoadPlugins(os.environ['ARNOLD_PLUGIN_PATH']) ai.AiASSLoad (ass, ai.AI_NODE_ALL) ai.AiRender() ai.AiEnd() # read out file ai.AiBegin() ai.AiMsgSetConsoleFlags(ai.AI_LOG_ALL) ai.AiASSLoad(ass, ai.AI_NODE_ALL) iter = ai.AiUniverseGetNodeIterator(ai.AI_NODE_ALL) while not ai.AiNodeIteratorFinished(iter): node = ai.AiNodeIteratorGetNext(iter) if ai.AiNodeIs( node, "driver_jpeg" ): imagefilename = ai.AiNodeGetStr( node, "filename" ) ai.AiNodeIteratorDestroy(iter) ai.AiEnd() if remove_ass: os.remove(ass) return imagefilename
def testTraceSets(self): sphere = GafferScene.Sphere() group = GafferScene.Group() group["in"][0].setInput(sphere["out"]) group["in"][1].setInput(sphere["out"]) set1 = GafferScene.Set() set1["name"].setValue("render:firstSphere") set1["paths"].setValue(IECore.StringVectorData(["/group/sphere"])) set1["in"].setInput(group["out"]) set2 = GafferScene.Set() set2["name"].setValue("render:secondSphere") set2["paths"].setValue(IECore.StringVectorData(["/group/sphere1"])) set2["in"].setInput(set1["out"]) set3 = GafferScene.Set() set3["name"].setValue("render:group") set3["paths"].setValue(IECore.StringVectorData(["/group"])) set3["in"].setInput(set2["out"]) set4 = GafferScene.Set() set4["name"].setValue("render:bothSpheres") set4["paths"].setValue( IECore.StringVectorData(["/group/sphere", "/group/sphere1"])) set4["in"].setInput(set3["out"]) render = GafferArnold.ArnoldRender() render["in"].setInput(set4["out"]) render["mode"].setValue(render.Mode.SceneDescriptionMode) render["fileName"].setValue(self.temporaryDirectory() + "/test.ass") render["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") firstSphere = arnold.AiNodeLookUpByName("/group/sphere") secondSphere = arnold.AiNodeLookUpByName("/group/sphere1") self.assertEqual( self.__arrayToSet( arnold.AiNodeGetArray(firstSphere, "trace_sets")), {"firstSphere", "group", "bothSpheres"}) self.assertEqual( self.__arrayToSet( arnold.AiNodeGetArray(secondSphere, "trace_sets")), {"secondSphere", "group", "bothSpheres"})
def testNoLinkedLightsOnLights(self): sphere = GafferScene.Sphere() meshLightShader = GafferArnold.ArnoldShader() meshLightShader.loadShader("flat") meshLightFilter = GafferScene.PathFilter() meshLightFilter["paths"].setValue(IECore.StringVectorData(["/sphere"])) meshLight = GafferArnold.ArnoldMeshLight() meshLight["in"].setInput(sphere["out"]) meshLight["filter"].setInput(meshLightFilter["out"]) meshLight["parameters"]["color"].setInput(meshLightShader["out"]) light1 = GafferArnold.ArnoldLight() light1.loadShader("point_light") light2 = GafferArnold.ArnoldLight() light2.loadShader("point_light") # Trigger light linking by unlinking a light light2["defaultLight"].setValue(False) group = GafferScene.Group() group["in"][0].setInput(meshLight["out"]) group["in"][1].setInput(light1["out"]) group["in"][2].setInput(light2["out"]) render = GafferArnold.ArnoldRender() render["in"].setInput(group["out"]) render["mode"].setValue(render.Mode.SceneDescriptionMode) render["fileName"].setValue(self.temporaryDirectory() + "/test.ass") render["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") sphere = arnold.AiNodeLookUpByName("/group/sphere") self.assertIsNotNone(sphere) self.assertEqual( arnold.AiArrayGetNumElements( arnold.AiNodeGetArray(sphere, "light_group")), 0) self.assertFalse(arnold.AiNodeGetBool(sphere, "use_light_group"))
def testRendererContextVariable( self ) : sphere = GafferScene.Sphere() sphere["name"].setValue( "sphere${scene:renderer}" ) render = GafferArnold.ArnoldRender() render["in"].setInput( sphere["out"] ) render["mode"].setValue( render.Mode.SceneDescriptionMode ) render["fileName"].setValue( self.temporaryDirectory() + "/test.ass" ) render["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) self.assertTrue( arnold.AiNodeLookUpByName( "/sphereArnold" ) is not None )
def testShaderNames(self): r = GafferScene.Private.IECoreScenePreview.Renderer.create( "IECoreArnold::Renderer", GafferScene.Private.IECoreScenePreview. Renderer.RenderType.SceneDescription, self.temporaryDirectory() + "/test.ass") shader1 = IECore.ObjectVector([ IECore.Shader("noise", parameters={"__handle": "myHandle"}), IECore.Shader("flat", parameters={"color": "link:myHandle"}), ]) o1 = r.object( "testPlane", IECore.MeshPrimitive.createPlane( IECore.Box2f(IECore.V2f(-1), IECore.V2f(1)))) o1.attributes( r.attributes(IECore.CompoundObject({"ai:surface": shader1}))) shader2 = IECore.ObjectVector([ IECore.Shader("noise", parameters={"__handle": "myHandle"}), IECore.Shader("standard", parameters={"Kd_color": "link:myHandle"}), ]) o2 = r.object( "testPlane", IECore.MeshPrimitive.createPlane( IECore.Box2f(IECore.V2f(-1), IECore.V2f(1)))) o2.attributes( r.attributes(IECore.CompoundObject({"ai:surface": shader2}))) del o1, o2 r.render() del r with IECoreArnold.UniverseBlock(): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") shaders = self.__allNodes(type=arnold.AI_NODE_SHADER) self.assertEqual(len(shaders), 4) self.assertEqual( len(set([arnold.AiNodeGetName(s) for s in shaders])), 4)
def testDefaultLightsMistakesDontForceLinking(self): light = GafferArnold.ArnoldLight() light.loadShader("point_light") sphere = GafferScene.Sphere() # It doesn't make sense to add a non-light to the "defaultLights" # set like this, but in the event of user error, we don't want to # emit light links unnecessarily. sphereSet = GafferScene.Set() sphereSet["in"].setInput(sphere["out"]) sphereSet["name"].setValue("defaultLights") sphereSet["paths"].setValue(IECore.StringVectorData(["/sphere"])) group = GafferScene.Group() group["in"][0].setInput(light["out"]) group["in"][1].setInput(sphereSet["out"]) render = GafferArnold.ArnoldRender() render["in"].setInput(group["out"]) render["mode"].setValue(render.Mode.SceneDescriptionMode) render["fileName"].setValue(self.temporaryDirectory() + "/test.ass") render["task"].execute() with IECoreArnold.UniverseBlock(writable=True): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") sphere = arnold.AiNodeLookUpByName("/group/sphere") self.assertIsNotNone(sphere) self.assertEqual( arnold.AiArrayGetNumElements( arnold.AiNodeGetArray(sphere, "light_group")), 0) self.assertFalse(arnold.AiNodeGetBool(sphere, "use_light_group"))
def testSceneDescription(self): r = GafferScene.Private.IECoreScenePreview.Renderer.create( "IECoreArnold::Renderer", GafferScene.Private.IECoreScenePreview. Renderer.RenderType.SceneDescription, self.temporaryDirectory() + "/test.ass") o = r.object( "testPlane", IECore.MeshPrimitive.createPlane( IECore.Box2f(IECore.V2f(-1), IECore.V2f(1)))) o.transform(IECore.M44f().translate(IECore.V3f(1, 2, 3))) r.render() del r with IECoreArnold.UniverseBlock(): arnold.AiASSLoad(self.temporaryDirectory() + "/test.ass") n = arnold.AiNodeLookUpByName("testPlane") self.assertTrue( arnold.AiNodeEntryGetType(arnold.AiNodeGetNodeEntry(n)), arnold.AI_NODE_SHAPE)
def testLightAndShadowLinking( self ) : sphere1 = GafferScene.Sphere() sphere2 = GafferScene.Sphere() attributes = GafferScene.StandardAttributes() arnoldAttributes = GafferArnold.ArnoldAttributes() light1 = GafferArnold.ArnoldLight() light1.loadShader( "point_light" ) light2 = GafferArnold.ArnoldLight() light2.loadShader( "point_light" ) group = GafferScene.Group() render = GafferArnold.ArnoldRender() attributes["in"].setInput( sphere1["out"] ) arnoldAttributes["in"].setInput( attributes["out"] ) group["in"][0].setInput( arnoldAttributes["out"] ) group["in"][1].setInput( light1["out"] ) group["in"][2].setInput( light2["out"] ) group["in"][3].setInput( sphere2["out"] ) render["in"].setInput( group["out"] ) # Illumination attributes["attributes"]["linkedLights"]["enabled"].setValue( True ) attributes["attributes"]["linkedLights"]["value"].setValue( "/group/light" ) # Shadows arnoldAttributes["attributes"]["shadowGroup"]["enabled"].setValue( True ) arnoldAttributes["attributes"]["shadowGroup"]["value"].setValue( "/group/light1" ) render["mode"].setValue( render.Mode.SceneDescriptionMode ) render["fileName"].setValue( self.temporaryDirectory() + "/test.ass" ) render["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) # the first sphere had linked lights sphere = arnold.AiNodeLookUpByName( "/group/sphere" ) # check illumination self.assertTrue( arnold.AiNodeGetBool( sphere, "use_light_group" ) ) lights = arnold.AiNodeGetArray( sphere, "light_group" ) self.assertEqual( arnold.AiArrayGetNumElements( lights ), 1 ) self.assertEqual( arnold.AiNodeGetName( arnold.AiArrayGetPtr( lights, 0 ) ), "light:/group/light" ) # check shadows self.assertTrue( arnold.AiNodeGetBool( sphere, "use_shadow_group" ) ) shadows = arnold.AiNodeGetArray( sphere, "shadow_group" ) self.assertEqual( arnold.AiArrayGetNumElements( shadows ), 1 ) self.assertEqual( arnold.AiNodeGetName( arnold.AiArrayGetPtr( shadows, 0 ) ), "light:/group/light1" ) # the second sphere does not have any light linking enabled sphere1 = arnold.AiNodeLookUpByName( "/group/sphere1" ) # check illumination self.assertFalse( arnold.AiNodeGetBool( sphere1, "use_light_group" ) ) lights = arnold.AiNodeGetArray( sphere1, "light_group" ) self.assertEqual( arnold.AiArrayGetNumElements( lights ), 0 ) # check shadows self.assertFalse( arnold.AiNodeGetBool( sphere1, "use_shadow_group" ) ) shadows = arnold.AiNodeGetArray( sphere1, "shadow_group" ) self.assertEqual( arnold.AiArrayGetNumElements( shadows ), 0 )
def testRenderRegion( self ) : s = Gaffer.ScriptNode() s["camera"] = GafferScene.Camera() s["options"] = GafferScene.StandardOptions() s["options"]["in"].setInput( s["camera"]["out"] ) s["options"]["options"]["renderCamera"]["enabled"].setValue( True ) s["options"]["options"]["renderCamera"]["value"].setValue( "/camera" ) 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" ) # Default region s["render"]["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) options = arnold.AiUniverseGetOptions() self.assertEqual( arnold.AiNodeGetInt( options, "xres" ), 640 ) self.assertEqual( arnold.AiNodeGetInt( options, "yres" ), 480 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_min_x" ), 0 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_max_x" ), 639 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_min_y" ), 0 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_max_y" ), 479 ) # Apply Crop Window s["options"]["options"]["renderCropWindow"]["enabled"].setValue( True ) s["options"]["options"]["renderCropWindow"]["value"].setValue( imath.Box2f( imath.V2f( 0.25, 0.5 ), imath.V2f( 0.75, 1.0 ) ) ) s["render"]["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) options = arnold.AiUniverseGetOptions() self.assertEqual( arnold.AiNodeGetInt( options, "xres" ), 640 ) self.assertEqual( arnold.AiNodeGetInt( options, "yres" ), 480 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_min_x" ), 160 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_max_x" ), 479 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_min_y" ), 240 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_max_y" ), 479 ) # Test Empty Crop Window s["options"]["options"]["renderCropWindow"]["value"].setValue( imath.Box2f() ) s["render"]["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) options = arnold.AiUniverseGetOptions() self.assertEqual( arnold.AiNodeGetInt( options, "xres" ), 640 ) self.assertEqual( arnold.AiNodeGetInt( options, "yres" ), 480 ) # Since Arnold doesn't support empty regions, we default to one pixel in the corner self.assertEqual( arnold.AiNodeGetInt( options, "region_min_x" ), 0 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_max_x" ), 0 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_min_y" ), 479 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_max_y" ), 479 ) # Apply Overscan s["options"]["options"]["renderCropWindow"]["enabled"].setValue( False ) s["options"]["options"]["overscan"]["enabled"].setValue( True ) s["options"]["options"]["overscan"]["value"].setValue( True ) s["options"]["options"]["overscanTop"]["enabled"].setValue( True ) s["options"]["options"]["overscanTop"]["value"].setValue( 0.1 ) s["options"]["options"]["overscanBottom"]["enabled"].setValue( True ) s["options"]["options"]["overscanBottom"]["value"].setValue( 0.2 ) s["options"]["options"]["overscanLeft"]["enabled"].setValue( True ) s["options"]["options"]["overscanLeft"]["value"].setValue( 0.3 ) s["options"]["options"]["overscanRight"]["enabled"].setValue( True ) s["options"]["options"]["overscanRight"]["value"].setValue( 0.4 ) s["render"]["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) options = arnold.AiUniverseGetOptions() self.assertEqual( arnold.AiNodeGetInt( options, "xres" ), 640 ) self.assertEqual( arnold.AiNodeGetInt( options, "yres" ), 480 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_min_x" ), -192 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_max_x" ), 640 + 255 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_min_y" ), -48 ) self.assertEqual( arnold.AiNodeGetInt( options, "region_max_y" ), 480 + 95 )
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 testShaderSubstitutions( self ) : s = Gaffer.ScriptNode() s["plane"] = GafferScene.Plane() s["planeAttrs"] = GafferScene.CustomAttributes() s["planeAttrs"]["in"].setInput( s["plane"]["out"] ) s["planeAttrs"]["attributes"].addChild( Gaffer.NameValuePlug( "A", Gaffer.StringPlug( "value", defaultValue = 'bar' ) ) ) s["planeAttrs"]["attributes"].addChild( Gaffer.NameValuePlug( "B", Gaffer.StringPlug( "value", defaultValue = 'foo' ) ) ) s["cube"] = GafferScene.Cube() s["cubeAttrs"] = GafferScene.CustomAttributes() s["cubeAttrs"]["in"].setInput( s["cube"]["out"] ) s["cubeAttrs"]["attributes"].addChild( Gaffer.NameValuePlug( "B", Gaffer.StringPlug( "value", defaultValue = 'override' ) ) ) s["parent"] = GafferScene.Parent() s["parent"]["in"].setInput( s["planeAttrs"]["out"] ) s["parent"]["children"][0].setInput( s["cubeAttrs"]["out"] ) s["parent"]["parent"].setValue( "/plane" ) s["shader"] = GafferArnold.ArnoldShader() s["shader"].loadShader( "image" ) s["shader"]["parameters"]["filename"].setValue( "<attr:A>/path/<attr:B>.tx" ) s["filter"] = GafferScene.PathFilter() s["filter"]["paths"].setValue( IECore.StringVectorData( [ "/plane" ] ) ) s["shaderAssignment"] = GafferScene.ShaderAssignment() s["shaderAssignment"]["in"].setInput( s["parent"]["out"] ) s["shaderAssignment"]["filter"].setInput( s["filter"]["out"] ) s["shaderAssignment"]["shader"].setInput( s["shader"]["out"] ) s["light"] = GafferArnold.ArnoldLight() s["light"].loadShader( "photometric_light" ) s["light"]["parameters"]["filename"].setValue( "/path/<attr:A>.ies" ) s["goboTexture"] = GafferArnold.ArnoldShader() s["goboTexture"].loadShader( "image" ) s["goboTexture"]["parameters"]["filename"].setValue( "<attr:B>/gobo.tx" ) s["gobo"] = GafferArnold.ArnoldShader() s["gobo"].loadShader( "gobo" ) s["gobo"]["parameters"]["slidemap"].setInput( s["goboTexture"]["out"] ) s["goboAssign"] = GafferScene.ShaderAssignment() s["goboAssign"]["in"].setInput( s["light"]["out"] ) s["goboAssign"]["shader"].setInput( s["gobo"]["out"] ) s["lightBlocker"] = GafferArnold.ArnoldLightFilter() s["lightBlocker"].loadShader( "light_blocker" ) s["lightBlocker"]["parameters"]["geometry_type"].setValue( "<attr:geometryType>" ) s["lightGroup"] = GafferScene.Group() s["lightGroup"]["name"].setValue( "lightGroup" ) s["lightGroup"]["in"][0].setInput( s["goboAssign"]["out"] ) s["lightGroup"]["in"][1].setInput( s["lightBlocker"]["out"] ) s["parent2"] = GafferScene.Parent() s["parent2"]["in"].setInput( s["shaderAssignment"]["out"] ) s["parent2"]["children"][0].setInput( s["lightGroup"]["out"] ) s["parent2"]["parent"].setValue( "/" ) s["globalAttrs"] = GafferScene.CustomAttributes() s["globalAttrs"]["in"].setInput( s["parent2"]["out"] ) s["globalAttrs"]["global"].setValue( True ) s["globalAttrs"]["attributes"].addChild( Gaffer.NameValuePlug( "A", Gaffer.StringPlug( "value", defaultValue = 'default1' ) ) ) s["globalAttrs"]["attributes"].addChild( Gaffer.NameValuePlug( "B", Gaffer.StringPlug( "value", defaultValue = 'default2' ) ) ) s["globalAttrs"]["attributes"].addChild( Gaffer.NameValuePlug( "geometryType", Gaffer.StringPlug( "value", defaultValue = 'cylinder' ) ) ) s["render"] = GafferArnold.ArnoldRender() s["render"]["in"].setInput( s["globalAttrs"]["out"] ) s["render"]["mode"].setValue( s["render"].Mode.SceneDescriptionMode ) s["render"]["fileName"].setValue( self.temporaryDirectory() + "/test.ass" ) s["render"]["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) plane = arnold.AiNodeLookUpByName( "/plane" ) shader = arnold.AiNodeGetPtr( plane, "shader" ) self.assertEqual( arnold.AiNodeGetStr( shader, "filename" ), "bar/path/foo.tx" ) cube = arnold.AiNodeLookUpByName( "/plane/cube" ) shader2 = arnold.AiNodeGetPtr( cube, "shader" ) self.assertEqual( arnold.AiNodeGetStr( shader2, "filename" ), "bar/path/override.tx" ) light = arnold.AiNodeLookUpByName( "light:/lightGroup/light" ) self.assertEqual( arnold.AiNodeGetStr( light, "filename" ), "/path/default1.ies" ) gobo = arnold.AiNodeGetPtr( light, "filters" ) goboTex = arnold.AiNodeGetLink( gobo, "slidemap" ) self.assertEqual( arnold.AiNodeGetStr( goboTex, "filename" ), "default2/gobo.tx" ) lightFilter = arnold.AiNodeLookUpByName( "lightFilter:/lightGroup/lightFilter" ) self.assertEqual( arnold.AiNodeGetStr( lightFilter, "geometry_type" ), "cylinder" )
def testLightAndShadowLinking( self ) : sphere1 = GafferScene.Sphere() sphere2 = GafferScene.Sphere() attributes = GafferScene.StandardAttributes() arnoldAttributes = GafferArnold.ArnoldAttributes() light1 = GafferArnold.ArnoldLight() light1.loadShader( "point_light" ) light2 = GafferArnold.ArnoldLight() light2.loadShader( "point_light" ) group = GafferScene.Group() group["in"].addChild( GafferScene.ScenePlug( "in1" ) ) group["in"].addChild( GafferScene.ScenePlug( "in2" ) ) group["in"].addChild( GafferScene.ScenePlug( "in3" ) ) group["in"].addChild( GafferScene.ScenePlug( "in4" ) ) evaluate = GafferScene.EvaluateLightLinks() render = GafferArnold.ArnoldRender() attributes["in"].setInput( sphere1["out"] ) arnoldAttributes["in"].setInput( attributes["out"] ) group["in"]["in1"].setInput( arnoldAttributes["out"] ) group["in"]["in2"].setInput( light1["out"] ) group["in"]["in3"].setInput( light2["out"] ) group["in"]["in4"].setInput( sphere2["out"] ) evaluate["in"].setInput( group["out"] ) render["in"].setInput( evaluate["out"] ) # Illumination attributes["attributes"]["linkedLights"]["enabled"].setValue( True ) attributes["attributes"]["linkedLights"]["value"].setValue( "/group/light /group/light1" ) # Shadows arnoldAttributes["attributes"]["shadowGroup"]["enabled"].setValue( True ) arnoldAttributes["attributes"]["shadowGroup"]["value"].setValue( "/group/light /group/light1" ) # make sure we pass correct data into the renderer self.assertEqual( set( render["in"].attributes( "/group/sphere" )["linkedLights"] ), set( IECore.StringVectorData( ["/group/light", "/group/light1"] ) ) ) self.assertEqual( set( render["in"].attributes( "/group/sphere" )["ai:visibility:shadow_group"] ), set( IECore.StringVectorData( ["/group/light", "/group/light1"] ) ) ) render["mode"].setValue( render.Mode.SceneDescriptionMode ) render["fileName"].setValue( self.temporaryDirectory() + "/test.ass" ) render["task"].execute() with IECoreArnold.UniverseBlock( writable = True ) : arnold.AiASSLoad( self.temporaryDirectory() + "/test.ass" ) # the first sphere had linked lights sphere = arnold.AiNodeLookUpByName( "/group/sphere" ) # check illumination lights = arnold.AiNodeGetArray( sphere, "light_group" ) lightNames = [] for i in range( arnold.AiArrayGetNumElements( lights.contents ) ): light = arnold.cast(arnold.AiArrayGetPtr(lights, i), arnold.POINTER(arnold.AtNode)) lightNames.append( arnold.AiNodeGetName(light.contents) ) doLinking = arnold.AiNodeGetBool( sphere, "use_light_group" ) self.assertEqual( set( lightNames ), { "light:/group/light", "light:/group/light1" } ) self.assertEqual( doLinking, True ) # check shadows shadows = arnold.AiNodeGetArray( sphere, "shadow_group" ) lightNames = [] for i in range( arnold.AiArrayGetNumElements( shadows.contents ) ): light = arnold.cast(arnold.AiArrayGetPtr(shadows, i), arnold.POINTER(arnold.AtNode)) lightNames.append( arnold.AiNodeGetName(light.contents) ) doLinking = arnold.AiNodeGetBool( sphere, "use_shadow_group" ) self.assertEqual( set( lightNames ), { "light:/group/light", "light:/group/light1" } ) self.assertEqual( doLinking, True ) # the second sphere does not have any light linking enabled sphere1 = arnold.AiNodeLookUpByName( "/group/sphere1" ) # check illumination lights = arnold.AiNodeGetArray( sphere1, "light_group" ) lightNames = [] for i in range( arnold.AiArrayGetNumElements( lights.contents ) ): light = arnold.cast(arnold.AiArrayGetPtr(lights, i), arnold.POINTER(arnold.AtNode)) lightNames.append( arnold.AiNodeGetName(light.contents) ) doLinking = arnold.AiNodeGetBool( sphere1, "use_light_group" ) self.assertEqual( lightNames, [] ) self.assertEqual( doLinking, False ) # check shadows shadows = arnold.AiNodeGetArray( sphere1, "shadow_group" ) lightNames = [] for i in range( arnold.AiArrayGetNumElements( shadows.contents ) ): light = arnold.cast(arnold.AiArrayGetPtr(shadows, i), arnold.POINTER(arnold.AtNode)) lightNames.append( arnold.AiNodeGetName(light.contents) ) doLinking = arnold.AiNodeGetBool( sphere1, "use_shadow_group" ) self.assertEqual( lightNames, [] ) self.assertEqual( doLinking, False )
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)