Exemple #1
0
    def _ValidateDistantLight(self):
        lightPrimPath = '/directionalLight1'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)
        distantLight = UsdLux.DistantLight(lightPrim)
        self.assertTrue(distantLight)

        self.assertTrue(Gf.IsClose(distantLight.GetIntensityAttr().Get(1),
            2, 1e-6))
        self.assertTrue(Gf.IsClose(distantLight.GetColorAttr().Get(1), Gf.Vec3f(1, 0.9, 0.8), 1e-6))

        self.assertTrue(Gf.IsClose(distantLight.GetAngleAttr().Get(1),
            1.5, 1e-6))
        self.assertTrue(Gf.IsClose(distantLight.GetAngleAttr().Get(5),
            2, 1e-6))

        rotateOp = distantLight.GetOrderedXformOps()
        self.assertEqual(rotateOp[0].GetOpType(), UsdGeom.XformOp.TypeRotateXYZ)
        self.assertTrue(UsdGeom.XformCommonAPI(distantLight))
        self.assertTrue(Gf.IsClose(rotateOp[0].Get(1), Gf.Vec3f(-20, -40, 0.0), 1e-6))
       

        self.assertTrue(lightPrim.HasAPI(UsdLux.ShadowAPI))
        shadowAPI = UsdLux.ShadowAPI(lightPrim)
        self.assertTrue(shadowAPI)

        self.assertTrue(shadowAPI.GetShadowEnableAttr().Get(1))
        self.assertTrue(Gf.IsClose(shadowAPI.GetShadowColorAttr().Get(1), Gf.Vec3f(0.1, 0.2, 0.3), 1e-6))
        return
Exemple #2
0
    def _ValidateAreaLight(self):
        lightPrimPath = '/areaLight1'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)
        rectLight = UsdLux.RectLight(lightPrim)
        self.assertTrue(rectLight)
        self.assertTrue(Gf.IsClose(rectLight.GetColorAttr().Get(), Gf.Vec3f(0.8, 0.7, 0.6), 1e-6))
        self.assertTrue(Gf.IsClose(rectLight.GetIntensityAttr().Get(), 1.2, 1e-6))
        
        # normalize didn't exist before Maya 2020
        if getMayaAPIVersion() > 2019:
            self.assertTrue(rectLight.GetNormalizeAttr().Get())
        
        self.assertTrue(lightPrim.HasAPI(UsdLux.ShadowAPI))
        shadowAPI = UsdLux.ShadowAPI(lightPrim)
        self.assertTrue(shadowAPI)

        (translateOp,rotateOp,scaleOp) = rectLight.GetOrderedXformOps()
        self.assertEqual(translateOp.GetOpType(), UsdGeom.XformOp.TypeTranslate)
        self.assertEqual(rotateOp.GetOpType(), UsdGeom.XformOp.TypeRotateXYZ)
        self.assertEqual(scaleOp.GetOpType(), UsdGeom.XformOp.TypeScale)
        self.assertTrue(UsdGeom.XformCommonAPI(rectLight))
        self.assertTrue(Gf.IsClose(translateOp.Get(1), Gf.Vec3d(8, 0, 10), 1e-6))
        self.assertTrue(Gf.IsClose(scaleOp.Get(1), Gf.Vec3f(4,3,2), 1e-6))
        self.assertTrue(Gf.IsClose(rotateOp.Get(1), Gf.Vec3f(0,23,0), 1e-6))
Exemple #3
0
    def _ValidateSpotLight(self):
        lightPrimPath = '/spotLight1'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)
        sphereLight = UsdLux.SphereLight(lightPrim)
        self.assertTrue(sphereLight)

        self.assertTrue(Gf.IsClose(sphereLight.GetColorAttr().Get(1), Gf.Vec3f(0.3, 1, 0.2), 1e-6))
        self.assertTrue(Gf.IsClose(sphereLight.GetColorAttr().Get(5), Gf.Vec3f(0, 0.2, 0.1), 1e-6))

        self.assertTrue(Gf.IsClose(sphereLight.GetIntensityAttr().Get(1), 0.8, 1e-6))
        self.assertTrue(Gf.IsClose(sphereLight.GetDiffuseAttr().Get(1), 0, 1e-6))
        self.assertTrue(Gf.IsClose(sphereLight.GetTreatAsPointAttr().Get(1), 1, 1e-6))
        self.assertTrue(Gf.IsClose(sphereLight.GetRadiusAttr().Get(1), 0, 1e-6))
    
        (translateOp,rotateOp) = sphereLight.GetOrderedXformOps()
        self.assertEqual(translateOp.GetOpType(), UsdGeom.XformOp.TypeTranslate)
        self.assertEqual(rotateOp.GetOpType(), UsdGeom.XformOp.TypeRotateXYZ)
        self.assertTrue(UsdGeom.XformCommonAPI(sphereLight))
        self.assertTrue(Gf.IsClose(translateOp.Get(1), Gf.Vec3d(10, 7, -8), 1e-6))
        self.assertTrue(Gf.IsClose(translateOp.Get(5), Gf.Vec3d(5, 3, 8), 1e-6))
        self.assertTrue(Gf.IsClose(rotateOp.Get(1), Gf.Vec3f(-45, 90, -5), 1e-6))
        
        self.assertTrue(lightPrim.HasAPI(UsdLux.ShadowAPI))
        shadowAPI = UsdLux.ShadowAPI(lightPrim)
        self.assertTrue(shadowAPI)

        self.assertTrue(lightPrim.HasAPI(UsdLux.ShapingAPI))
        shapingAPI = UsdLux.ShapingAPI(lightPrim)
        self.assertTrue(shapingAPI)
        self.assertTrue(Gf.IsClose(shapingAPI.GetShapingConeAngleAttr().Get(1), 25, 1e-6))
        self.assertTrue(Gf.IsClose(shapingAPI.GetShapingConeSoftnessAttr().Get(1), 0.4, 1e-6))
        self.assertTrue(Gf.IsClose(shapingAPI.GetShapingFocusAttr().Get(1), 8, 1e-6))
Exemple #4
0
def emit_default_light(app, light_name, usd_tfm, visibility, usd_prim, light_type, xsi_parent, up_key, ignore_tfm):
    xsi_light = None
    if light_type == "DistantLight":
        xsi_light = app.GetPrimLight("Infinite.Preset", light_name, xsi_parent)
        usd_light = UsdLux.DistantLight(usd_prim)
        # for distance we set transform
        utils.set_xsi_transform(app, xsi_light, usd_tfm, up_key=up_key, add_tfm=usd_light.GetLocalTransformation())
        utils.set_xsi_visibility(xsi_light, visibility)
        # and diffuse and specular params
        set_import_diffuse_param(app, xsi_light, usd_light)
        set_import_specular_param(app, xsi_light, usd_light)
    else:  # all other lights are point lights
        if light_type in ["SphereLight", "RectLight", "DiskLight", "CylinderLight"]:  # portal and dome lights are not supported by default lights
            xsi_light = app.GetPrimLight("Point.Preset", light_name, xsi_parent)
            # cast ptim to light
            usd_light = UsdLux.SphereLight(usd_prim) if light_type == "SphereLight" else (UsdLux.RectLight(usd_prim) if light_type == "RectLight" else (UsdLux.DiskLight(usd_prim) if light_type == "DiskLight" else UsdLux.CylinderLight(usd_prim)))
            # set transform
            utils.set_xsi_transform(app, xsi_light, usd_tfm, up_key=up_key, add_tfm=usd_light.GetLocalTransformation())
            utils.set_xsi_visibility(xsi_light, visibility)
            # set diffuse and specular
            set_import_diffuse_param(app, xsi_light, usd_light)
            set_import_specular_param(app, xsi_light, usd_light)
            # enable area light
            xsi_light.Parameters("LightArea").Value = True
            set_import_light_geometry(app, xsi_light, usd_light, light_type)
    return xsi_light
Exemple #5
0
    def __init__(self):
        AttributesContainerBase.__init__(self)

        attribute = self.define_attribute("Intensity")
        #attribute.construct_usd_attribute = lambda usd_node : usd_node.GetPrim().CreateAttribute("intensity", Sdf.ValueTypeNames.Double)
        attribute.construct_usd_attribute = lambda usd_node: UsdLux.Light(
            usd_node).GetIntensityAttr()
        attribute.get_from_usd = lambda usd_node: usd_unreal.utils.get_usd_attribute_value(
            usd_node.GetPrim(), "intensity")
        attribute.unreal_property_path = ["light_component", "intensity"]
        attribute.get_from_actor = lambda actor: actor.light_component.intensity

        attribute = self.define_attribute("LightColor", 3)
        attribute.construct_usd_attribute = lambda usd_node: UsdLux.Light(
            usd_node).GetColorAttr()
        attribute.convert_unreal_to_usd = lambda color: Gf.Vec3f(color)
        attribute.get_from_usd = lambda usd_node: usd_unreal.utils.get_usd_attribute_value(
            usd_node.GetPrim(), "color")
        attribute.sequencer_channel_names = ["Color.R", "Color.G", "Color.B"]
        attribute.get_from_actor = lambda actor: LightAttributes.get_light_color(
            actor.light_component)
        attribute.set_on_unreal_actor = lambda actor, value: actor.light_component.set_light_color(
            value)

        attribute = self.define_attribute("CastShadows")
        attribute.construct_usd_attribute = lambda usd_node: UsdLux.ShadowAPI(
            usd_node).CreateShadowEnableAttr()
        attribute.get_from_usd = lambda usd_node: usd_unreal.utils.get_usd_attribute_value(
            usd_node, "shadow:enable")
        attribute.unreal_property_path = ["light_component", "cast_shadows"]
        attribute.export_compacted_boolean_keys = True
        attribute.get_from_actor = lambda actor: actor.light_component.cast_shadows

        def get_temperature_from_light_component(component):
            return component.temperature if not isinstance(
                component, unreal.SkyLightComponent) else None

        attribute = self.define_attribute("Temperature")
        attribute.construct_usd_attribute = lambda usd_node: UsdLux.Light(
            usd_node).GetColorTemperatureAttr()
        attribute.get_from_usd = lambda usd_node: usd_unreal.utils.get_usd_attribute_value(
            usd_node.GetPrim(), "colorTemperature")
        attribute.unreal_property_path = ["light_component", "temperature"]
        attribute.get_from_actor = lambda actor: get_temperature_from_light_component(
            actor.light_component)

        def get_use_temperature_from_light_component(component):
            return component.use_temperature if not isinstance(
                component, unreal.SkyLightComponent) else None

        attribute = self.define_attribute("UseTemperature")
        attribute.construct_usd_attribute = lambda usd_node: UsdLux.Light(
            usd_node).GetEnableColorTemperatureAttr()
        attribute.get_from_usd = lambda usd_node: usd_unreal.utils.get_usd_attribute_value(
            usd_node.GetPrim(), "enableColorTemperature")
        attribute.unreal_property_path = ["light_component", "use_temperature"]
        attribute.get_from_actor = lambda actor: get_use_temperature_from_light_component(
            actor.light_component)
        attribute.export_compacted_boolean_keys = True
Exemple #6
0
 def test_BlackbodySpectrum(self):
     warm_color = UsdLux.BlackbodyTemperatureAsRgb(1000)
     whitepoint = UsdLux.BlackbodyTemperatureAsRgb(6500)
     cool_color = UsdLux.BlackbodyTemperatureAsRgb(10000)
     # Whitepoint is ~= (1,1,1)
     assert Gf.IsClose(whitepoint, Gf.Vec3f(1.0), 0.1)
     # Warm has more red than green or blue
     assert warm_color[0] > warm_color[1]
     assert warm_color[0] > warm_color[2]
     # Cool has more blue than red or green
     assert cool_color[2] > cool_color[0]
     assert cool_color[2] > cool_color[1]
Exemple #7
0
 def test_FilterLinking(self):
     light_path = '/Lights/FilterLinking/filter_exclude_a'
     light = UsdLux.Light(stage.GetPrimAtPath(light_path))
     filter_paths = light.GetFiltersRel().GetForwardedTargets()
     self.assertEqual(len(filter_paths), 1)
     light_filter = UsdLux.LightFilter(stage.GetPrimAtPath(filter_paths[0]))
     self.assertEqual(light_filter.GetPath(),
                      '/Lights/FilterLinking/filter')
     links = light_filter.GetFilterLinkCollectionAPI()
     query = links.ComputeMembershipQuery()
     self.assertFalse(query.IsPathIncluded('/Geom/a'))
     self.assertTrue(query.IsPathIncluded('/Geom/b'))
Exemple #8
0
    def _ValidateUsdLuxShadowAPI(self):
        lightPrimPath = '/RfMLightsTest/Lights/RectLight'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)

        self.assertTrue(lightPrim.HasAPI(UsdLux.ShadowAPI))

        shadowAPI = UsdLux.ShadowAPI(lightPrim)
        self.assertTrue(shadowAPI)

        self.assertTrue(shadowAPI.GetShadowEnableAttr().Get())

        expectedShadowColor = Gf.Vec3f(0.6)
        self.assertTrue(
            Gf.IsClose(shadowAPI.GetShadowColorAttr().Get(),
                       expectedShadowColor, 1e-6))

        expectedShadowDistance = -0.6
        self.assertTrue(
            Gf.IsClose(shadowAPI.GetShadowDistanceAttr().Get(),
                       expectedShadowDistance, 1e-6))

        expectedShadowFalloff = -0.6
        self.assertTrue(
            Gf.IsClose(shadowAPI.GetShadowFalloffAttr().Get(),
                       expectedShadowFalloff, 1e-6))

        expectedShadowFalloffGamma = 0.6
        self.assertTrue(
            Gf.IsClose(shadowAPI.GetShadowFalloffGammaAttr().Get(),
                       expectedShadowFalloffGamma, 1e-6))
Exemple #9
0
    def _ValidateUsdLuxShadowAPI(self):
        lightPrimPath = '/RfMLightsTest/Lights/RectLight'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)

        self.assertTrue(lightPrim.HasAPI(UsdLux.ShadowAPI))

        shadowAPI = UsdLux.ShadowAPI(lightPrim)
        self.assertTrue(shadowAPI)

        # Shadows are enabled by default, and we author sparsely, so there
        # should NOT be an opinion.
        self.assertFalse(
            shadowAPI.GetShadowEnableAttr().HasAuthoredValueOpinion())

        expectedShadowColor = Gf.Vec3f(0.5)
        self.assertTrue(Gf.IsClose(shadowAPI.GetShadowColorAttr().Get(),
            expectedShadowColor, 1e-6))

        expectedShadowDistance = -0.5
        self.assertTrue(Gf.IsClose(shadowAPI.GetShadowDistanceAttr().Get(),
            expectedShadowDistance, 1e-6))

        expectedShadowFalloff = -0.5
        self.assertTrue(Gf.IsClose(shadowAPI.GetShadowFalloffAttr().Get(),
            expectedShadowFalloff, 1e-6))

        expectedShadowFalloffGamma = 0.5
        self.assertTrue(Gf.IsClose(shadowAPI.GetShadowFalloffGammaAttr().Get(),
            expectedShadowFalloffGamma, 1e-6))
Exemple #10
0
    def _ValidateUsdLuxShapingAPI(self):
        lightPrimPath = '/RfMLightsTest/Lights/DiskLight'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)

        self.assertTrue(lightPrim.HasAPI(UsdLux.ShapingAPI))

        shapingAPI = UsdLux.ShapingAPI(lightPrim)
        self.assertTrue(shapingAPI)

        expectedFocus = 0.1
        self.assertTrue(Gf.IsClose(shapingAPI.GetShapingFocusAttr().Get(),
            expectedFocus, 1e-6))

        expectedFocusTint = Gf.Vec3f(0.1)
        self.assertTrue(Gf.IsClose(shapingAPI.GetShapingFocusTintAttr().Get(),
            expectedFocusTint, 1e-6))

        expectedConeAngle = 91.0
        self.assertTrue(Gf.IsClose(shapingAPI.GetShapingConeAngleAttr().Get(),
            expectedConeAngle, 1e-6))

        expectedConeSoftness = 0.1
        self.assertTrue(Gf.IsClose(shapingAPI.GetShapingConeSoftnessAttr().Get(),
            expectedConeSoftness, 1e-6))

        expectedProfilePath = './DiskLight_profile.ies'
        self.assertEqual(shapingAPI.GetShapingIesFileAttr().Get(),
            expectedProfilePath)

        expectedProfileScale = 1.1
        self.assertTrue(Gf.IsClose(shapingAPI.GetShapingIesAngleScaleAttr().Get(),
            expectedProfileScale, 1e-6))
Exemple #11
0
 def test_LinkageQueries(self):
     test_cases = (
         ('/Lights/DefaultLinkage/include_all', '/Geom', True),
         ('/Lights/DefaultLinkage/include_all', '/Geom/a', True),
         ('/Lights/DefaultLinkage/include_all', '/Geom/a/sub_scope', True),
         ('/Lights/SimpleInclude/include_a', '/Geom', False),
         ('/Lights/SimpleInclude/include_a', '/Geom/a', True),
         ('/Lights/SimpleInclude/include_a', '/Geom/a/sub_scope', True),
         ('/Lights/SimpleInclude/include_a', '/Geom/b', False),
         ('/Lights/SimpleExclude/exclude_a', '/Geom', True),
         ('/Lights/SimpleExclude/exclude_a', '/Geom/a', False),
         ('/Lights/SimpleExclude/exclude_a', '/Geom/a/sub_scope', False),
         ('/Lights/SimpleExclude/exclude_a', '/Geom/b', True),
         ('/Lights/FaceSetLinking/include_faceSet_example', '/', False),
         ('/Lights/FaceSetLinking/include_faceSet_example', '/Geom', False),
         ('/Lights/FaceSetLinking/include_faceSet_example',
          '/Geom/meshWithFaceSet', False),
         ('/Lights/FaceSetLinking/include_faceSet_example',
          '/Geom/meshWithFaceSet/faceSet', True),
     )
     for light_path, test_path, expected_result in test_cases:
         light = UsdLux.Light(stage.GetPrimAtPath(light_path))
         links = light.GetLightLinkCollectionAPI()
         query = links.ComputeMembershipQuery()
         actual_result = query.IsPathIncluded(test_path)
         self.assertEqual(actual_result, expected_result)
Exemple #12
0
    def test_LinkageAuthoring(self):
        stage = Usd.Stage.CreateInMemory()
        geom_scope = UsdGeom.Scope.Define(stage, '/Geom')
        sphere = UsdGeom.Sphere.Define(stage, '/Geom/Sphere')
        light_scope = UsdGeom.Scope.Define(stage, '/Lights')
        light_1 = UsdLux.SphereLight.Define(stage, '/Lights/light_1')
        light_1_links = UsdLux.Light(light_1).GetLightLinkCollectionAPI()

        # Schema default: link everything
        query = light_1_links.ComputeMembershipQuery()
        self.assertTrue(query.IsPathIncluded(geom_scope.GetPath()))
        self.assertTrue(query.IsPathIncluded(sphere.GetPath()))
        self.assertTrue(query.IsPathIncluded('/RandomOtherPath'))

        # Exclude /Geom.
        light_1_links.ExcludePath('/Geom')
        query = light_1_links.ComputeMembershipQuery()
        self.assertFalse(query.IsPathIncluded(geom_scope.GetPath()))
        self.assertFalse(query.IsPathIncluded(sphere.GetPath()))
        self.assertTrue(query.IsPathIncluded('/RandomOtherPath'))

        # Include /Geom/Sphere
        light_1_links.IncludePath('/Geom/Sphere')
        query = light_1_links.ComputeMembershipQuery()
        self.assertFalse(query.IsPathIncluded(geom_scope.GetPath()))
        self.assertTrue(query.IsPathIncluded(sphere.GetPath()))
        self.assertTrue(query.IsPathIncluded('/Geom/Sphere/Child'))
        self.assertTrue(query.IsPathIncluded('/RandomOtherPath'))
Exemple #13
0
    def _ValidateUsdLuxDomeLightTextureFile(self):
        lightPrimPath = '/RfMLightsTest/Lights/DomeLight'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)

        domeLight = UsdLux.DomeLight(lightPrim)
        self.assertTrue(domeLight)

        expectedTextureFile = './DomeLight_texture.tex'
        self.assertEqual(domeLight.GetTextureFileAttr().Get(),
            expectedTextureFile)
Exemple #14
0
    def _ValidateUsdLuxDistantLightAngle(self):
        lightPrimPath = '/RfMLightsTest/Lights/DistantLight'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)

        distantLight = UsdLux.DistantLight(lightPrim)
        self.assertTrue(distantLight)

        expectedAngle = 0.73
        self.assertTrue(Gf.IsClose(distantLight.GetAngleAttr().Get(),
            expectedAngle, 1e-6))
Exemple #15
0
    def _ValidatePointLight(self):
        lightPrimPath = '/pointLight1'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)
        sphereLight = UsdLux.SphereLight(lightPrim)
        self.assertTrue(sphereLight)
        self.assertTrue(Gf.IsClose(sphereLight.GetColorAttr().Get(1), Gf.Vec3f(1, 0.5, 0.1), 1e-6))

        self.assertTrue(Gf.IsClose(sphereLight.GetIntensityAttr().Get(1), 0.5, 1e-6))
        self.assertTrue(Gf.IsClose(sphereLight.GetIntensityAttr().Get(5), 2, 1e-6))
        self.assertTrue(Gf.IsClose(sphereLight.GetSpecularAttr().Get(1), 0, 1e-6))
        self.assertTrue(Gf.IsClose(sphereLight.GetTreatAsPointAttr().Get(1), 1, 1e-6))
        self.assertTrue(Gf.IsClose(sphereLight.GetRadiusAttr().Get(1), 0, 1e-6))
    
        translateOp = sphereLight.GetOrderedXformOps()
        self.assertEqual(translateOp[0].GetOpType(), UsdGeom.XformOp.TypeTranslate)
        self.assertTrue(UsdGeom.XformCommonAPI(sphereLight))
        self.assertTrue(Gf.IsClose(translateOp[0].Get(1), Gf.Vec3d(-10, 10, 0.0), 1e-6))
Exemple #16
0
    def _ValidateDiskLightXformAnimation(self):
        lightPrimPath = '/RfMLightsTest/Lights/DiskLight'
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)

        diskLight = UsdLux.DiskLight(lightPrim)
        self.assertTrue(diskLight)

        xformOps = diskLight.GetOrderedXformOps()
        self.assertEqual(len(xformOps), 1)

        translateOp = xformOps[0]

        self.assertEqual(translateOp.GetOpName(), 'xformOp:translate')
        self.assertEqual(translateOp.GetOpType(), UsdGeom.XformOp.TypeTranslate)

        for frame in xrange(int(self.START_TIMECODE), int(self.END_TIMECODE + 1.0)):
            expectedTranslation = Gf.Vec3d(1.0, float(frame), 1.0)
            self.assertTrue(
                Gf.IsClose(translateOp.Get(frame), expectedTranslation, 1e-6))
Exemple #17
0
def emit_sycles_light(app, light_name, usd_tfm, visibility, usd_prim, light_type, xsi_parent, up_key, ignore_tfm):
    xsi_light = None
    usd_light = None
    # cylinder light is not suported by cycles lighst
    if light_type == "RectLight":
        xsi_light = app.GetPrim("cyclesArea", light_name, xsi_parent)
        usd_light = UsdLux.RectLight(usd_prim)
        # set width and height
        set_import_parameter(app, xsi_light, "sizeU", usd_light.GetWidthAttr())
        set_import_parameter(app, xsi_light, "sizeV", usd_light.GetHeightAttr())
    elif light_type == "DiskLight":
        xsi_light = app.GetPrim("cyclesArea", light_name, xsi_parent)
        usd_light = UsdLux.DiskLight(usd_prim)
        xsi_light.Parameters("shape").Value = 1
        set_import_parameter(app, xsi_light, "sizeU", usd_light.GetRadiusAttr())
        set_import_parameter(app, xsi_light, "sizeV", usd_light.GetRadiusAttr())
    elif light_type == "LightPortal":
        xsi_light = app.GetPrim("cyclesArea", light_name, xsi_parent)
        usd_light = UsdLux.LightPortal(usd_prim)
        xsi_light.Parameters("is_portal").Value = True
    elif light_type == "SphereLight":
        xsi_light = app.GetPrim("cyclesPoint", light_name, xsi_parent)
        usd_light = UsdLux.SphereLight(usd_prim)
        set_import_parameter(app, xsi_light, "size", usd_light.GetRadiusAttr())
    elif light_type == "DistantLight":
        xsi_light = app.GetPrim("cyclesSun", light_name, xsi_parent)
        usd_light = UsdLux.DistantLight(usd_prim)
        set_import_parameter(app, xsi_light, "angle", usd_light.GetAngleAttr())
    elif light_type == "DomeLight":
        xsi_light = app.GetPrim("cyclesBackground", light_name, xsi_parent)
        usd_light = UsdLux.DomeLight(usd_prim)
    if xsi_light is not None:
        # set transform
        utils.set_xsi_transform(app, xsi_light, usd_tfm, up_key=up_key, add_tfm=usd_light.GetLocalTransformation())
        utils.set_xsi_visibility(xsi_light, visibility)

        # for all lights (except dome light and portal) we can set diffuse, specular, intensity
        if usd_light is not None and light_type != "DomeLight" and light_type != "LightPortal":
            set_import_parameter(app, xsi_light, "use_diffuse", usd_light.GetDiffuseAttr())
            set_import_parameter(app, xsi_light, "use_glossy", usd_light.GetSpecularAttr())
            set_import_parameter(app, xsi_light, "power", usd_light.CreateIntensityAttr())

    return xsi_light
def sync(obj_prim, obj: bpy.types.Object, **kwargs):
    """ Creates pyrpr.Light from obj.data: bpy.types.Light """
    light = obj.data
    stage = obj_prim.GetStage()
    context = bpy.context
    is_preview_render = kwargs.get('is_preview_render', False)
    log("sync", light, obj)

    light_path = obj_prim.GetPath().AppendChild(
        Tf.MakeValidIdentifier(light.name))

    if light.type == 'POINT':
        usd_light = UsdLux.SphereLight.Define(stage, light_path)

        size = light.shadow_soft_size
        usd_light.CreateRadiusAttr(size)

    elif light.type in (
            'SUN', 'HEMI'):  # just in case old scenes will have outdated Hemi
        usd_light = UsdLux.DistantLight.Define(stage, light_path)
        angle = math.degrees(light.angle)
        usd_light.CreateAngleAttr(angle)
        intensity_attr = usd_light.CreateIntensityAttr()

        usd_utils.add_delegate_variants(
            obj_prim,
            {
                'GL': lambda: intensity_attr.
                Set(light.energy * 1736000000
                    ),  # coefficient approximated to follow RPR results
                'RPR': lambda: intensity_attr.Set(light.energy)
            })

    elif light.type == 'SPOT':
        usd_light = UsdLux.SphereLight.Define(stage, light_path)
        usd_prim = stage.GetPrimAtPath(light_path)

        usd_light.CreateTreatAsPointAttr(1)

        spot_size = math.degrees(light.spot_size)

        usd_shaping = UsdLux.ShapingAPI(usd_prim)
        usd_shaping.CreateShapingConeAngleAttr(spot_size / 2)
        usd_shaping.CreateShapingConeSoftnessAttr(light.spot_blend)

        usd_shaping.Apply(usd_prim)

    elif light.type == 'AREA':
        shape_type = light.shape

        if shape_type == 'SQUARE':
            usd_light = UsdLux.RectLight.Define(stage, light_path)
            usd_light.CreateWidthAttr(light.size)
            usd_light.CreateHeightAttr(light.size)

        elif shape_type == 'RECTANGLE':
            usd_light = UsdLux.RectLight.Define(stage, light_path)
            usd_light.CreateWidthAttr(light.size)
            usd_light.CreateHeightAttr(light.size_y)

        elif shape_type == 'DISK':
            usd_light = UsdLux.DiskLight.Define(stage, light_path)
            usd_light.CreateRadiusAttr(light.size /
                                       2)  # light.size is diameter

        else:  # shape_type == 'ELLIPSE':
            usd_light = UsdLux.DiskLight.Define(stage, light_path)
            usd_light.CreateRadiusAttr((light.size + light.size_y) /
                                       4)  # average of light.size is diameter

    else:
        raise ValueError("Unsupported light type", light, light.type)

    power = get_radiant_power(light)

    color_attr = usd_light.CreateColorAttr()

    if is_preview_render:
        # Material Previews are overly bright, that's why
        # decreasing light intensity for material preview by 10 times
        power *= 0.1

    color_attr.Set(tuple(power))
Exemple #19
0
    def test_SdrShaderNodesForLights(self):
        """
        Test the automatic registration of SdrShaderNodes for all the UsdLux
        light types.
        """
        # Get all the derived types of UsdLuxLight
        lightTypes = Tf.Type(UsdLux.Light).GetAllDerivedTypes()
        self.assertTrue(lightTypes)
        # Verify that at least one known light type is in our list to guard
        # against this giving false positives if no light types are available.
        self.assertIn(UsdLux.RectLight, lightTypes)

        stage = Usd.Stage.CreateInMemory()
        prim = stage.DefinePrim("/Prim")

        for lightType in lightTypes:
            # Every concrete light type will have an SdrShaderNode with source
            # type 'USD' registered for it under its USD schema type name.
            typeName = Usd.SchemaRegistry.GetConcreteSchemaTypeName(lightType)
            node = Sdr.Registry().GetNodeByName(typeName, ['USD'])
            self.assertTrue(node.IsValid())

            # Set the prim to the light type so we can cross check node inputs
            # with the light prim built-in properties.
            prim.SetTypeName(typeName)
            light = UsdLux.Light(prim)
            self.assertTrue(light)

            # Names, identifier, and role for the node all match the USD schema
            # type name
            self.assertEqual(node.GetIdentifier(), typeName)
            self.assertEqual(node.GetName(), typeName)
            self.assertEqual(node.GetImplementationName(), typeName)
            self.assertEqual(node.GetRole(), typeName)
            self.assertTrue(node.GetInfoString().startswith(typeName))

            # The context is always 'light'. Source type is 'USD'
            self.assertEqual(node.GetContext(), 'light')
            self.assertEqual(node.GetSourceType(), 'USD')

            # Help string is generated and encoded in the node's metadata (no
            # need to verify the specific wording).
            self.assertTrue(set(node.GetMetadata().keys()), {'primvars', 'help'})
            self.assertEqual(node.GetMetadata()["help"], node.GetHelp())

            # Source code and URIs are all empty.
            self.assertFalse(node.GetSourceCode())
            self.assertFalse(node.GetResolvedDefinitionURI())
            self.assertFalse(node.GetResolvedImplementationURI())

            # Other classifications are left empty.
            self.assertFalse(node.GetCategory())
            self.assertFalse(node.GetDepartments())
            self.assertFalse(node.GetFamily())
            self.assertFalse(node.GetLabel())
            self.assertFalse(node.GetVersion())
            self.assertFalse(node.GetAllVstructNames())
            self.assertEqual(node.GetPages(), [''])

            # Helper for comparing an SdrShaderProperty from node to the 
            # corresponding UsdShadeInput/UsdShadeOutput from a UsdLuxLight
            def _CompareLightPropToNodeProp(nodeInput, lightInput):
                # Input names and default values match.
                self.assertEqual(nodeInput.GetName(), lightInput.GetBaseName())
                self.assertEqual(nodeInput.GetDefaultValue(),
                                 lightInput.GetAttr().Get())

                # Some USD property types don't match exactly one to one and are
                # converted to different types. In particular relevance to 
                # lights, Bool becomes Int and Token becomes String.
                expectedTypeName = lightInput.GetTypeName()
                if expectedTypeName == Sdf.ValueTypeNames.Bool:
                    expectedTypeName = Sdf.ValueTypeNames.Int 
                elif expectedTypeName == Sdf.ValueTypeNames.Token:
                    expectedTypeName = Sdf.ValueTypeNames.String 
                # Verify the node's input type maps back to USD property's type
                # (with the noted above exceptions).
                self.assertEqual(
                    nodeInput.GetTypeAsSdfType()[0], expectedTypeName,
                    msg="Type {} != {}".format(
                        str(nodeInput.GetTypeAsSdfType()[0]),
                        str(expectedTypeName)))
                # If the USD property type is an Asset, it will be listed in 
                # the node's asset indentifier inputs.
                if expectedTypeName == Sdf.ValueTypeNames.Asset:
                    self.assertIn(nodeInput.GetName(), 
                                  node.GetAssetIdentifierInputNames())

            # There will be a one to one correspondence between node inputs
            # and light prim inputs.
            nodeInputs = [node.GetInput(i) for i in node.GetInputNames()]
            lightInputs = light.GetInputs()
            for nodeInput, lightInput in zip(nodeInputs, lightInputs):
                self.assertFalse(nodeInput.IsOutput())
                _CompareLightPropToNodeProp(nodeInput, lightInput)

            # There will also be a one to one correspondence between node 
            # outputs and light prim outputs.
            nodeOutputs = [node.GetOutput(i) for i in node.GetOutputNames()]
            lightOutputs = light.GetOutputs()
            for nodeOutput, lightOutput in zip(nodeOutputs, lightOutputs):
                self.assertTrue(nodeOutput.IsOutput())
                _CompareLightPropToNodeProp(nodeOutput, lightOutput)

            # The reverse is tested just above, but for all asset identifier
            # inputs listed for the node there is a corresponding asset value
            # input property on the light prim.
            for inputName in node.GetAssetIdentifierInputNames():
                self.assertEqual(light.GetInput(inputName).GetTypeName(),
                                 Sdf.ValueTypeNames.Asset)

            # These primvars come from sdrMetadata on the prim itself which
            # isn't supported for light schemas so it will alwasy be empty.
            self.assertFalse(node.GetPrimvars())
            # sdrMetadata on input properties is supported so additional 
            # primvar properties will correspond to light inputs with that 
            # metadata set.
            for propName in node.GetAdditionalPrimvarProperties():
                self.assertTrue(light.GetInput(propName).GetSdrMetadataByKey(
                    'primvarProperty'))

            # Default input can also be specified in the property's sdrMetadata.
            if node.GetDefaultInput():
                defaultLightInput = light.GetInput(
                    node.GetDefaultInput().GetName())
                self.assertTrue(lightInput.GetSdrMetadataByKey('defaultInput'))
Exemple #20
0
    def test_SdrShaderNodesForLights(self):
        """
        Test the automatic registration of SdrShaderNodes for all the UsdLux
        light types.
        """

        # The expected shader node inputs that should be found for all of our
        # UsdLux light types.
        expectedLightInputNames = [
            # LightAPI
            'color', 
            'colorTemperature', 
            'diffuse', 
            'enableColorTemperature', 
            'exposure', 
            'intensity', 
            'normalize', 
            'specular',

            # ShadowAPI
            'shadow:color',
            'shadow:distance',
            'shadow:enable',
            'shadow:falloff',
            'shadow:falloffGamma',

            # ShapingAPI
            'shaping:cone:angle',
            'shaping:cone:softness',
            'shaping:focus',
            'shaping:focusTint',
            'shaping:ies:angleScale',
            'shaping:ies:file',
            'shaping:ies:normalize'
            ]

        # Map of the names of the expected light nodes to the additional inputs
        # we expect for those types.
        expectedLightNodes = {
            'CylinderLight' : ['length', 'radius'],
            'DiskLight' : ['radius'],
            'DistantLight' : ['angle'],
            'DomeLight' : ['texture:file', 'texture:format'],
            'GeometryLight' : [],
            'PortalLight' : [],
            'RectLight' : ['width', 'height', 'texture:file'],
            'SphereLight' : ['radius'],
            'MeshLight' : [],
            'VolumeLight' : []
            }

        # Get all the derived types of UsdLuxBoundableLightBase and 
        # UsdLuxNonboundableLightBase that are defined in UsdLux
        lightTypes = list(filter(
            Plug.Registry().GetPluginWithName("usdLux").DeclaresType,
            Tf.Type(UsdLux.BoundableLightBase).GetAllDerivedTypes() +
            Tf.Type(UsdLux.NonboundableLightBase).GetAllDerivedTypes()))
        self.assertTrue(lightTypes)

        # Augment lightTypes to include MeshLightAPI and VolumeLightAPI
        lightTypes.append(
            Tf.Type.FindByName('UsdLuxMeshLightAPI'))
        lightTypes.append(
            Tf.Type.FindByName('UsdLuxVolumeLightAPI'))

        # Verify that at least one known light type is in our list to guard
        # against this giving false positives if no light types are available.
        self.assertIn(UsdLux.RectLight, lightTypes)
        self.assertEqual(len(lightTypes), len(expectedLightNodes))

        stage = Usd.Stage.CreateInMemory()
        prim = stage.DefinePrim("/Prim")

        usdSchemaReg = Usd.SchemaRegistry()
        for lightType in lightTypes:

            print("Test SdrNode for schema type " + str(lightType))
            
            if usdSchemaReg.IsAppliedAPISchema(lightType):
                prim.ApplyAPI(lightType)
            else:
                typeName = usdSchemaReg.GetConcreteSchemaTypeName(lightType)
                if not typeName:
                    continue
                prim.SetTypeName(typeName)
            light = UsdLux.LightAPI(prim)
            self.assertTrue(light)
            sdrIdentifier = light.GetShaderId([])
            self.assertTrue(sdrIdentifier)
            prim.ApplyAPI(UsdLux.ShadowAPI)
            prim.ApplyAPI(UsdLux.ShapingAPI)

            # Every concrete light type and some API schemas (with appropriate
            # shaderId as sdr Identifier) in usdLux domain will have an 
            # SdrShaderNode with source type 'USD' registered for it under its 
            # USD schema type name. 
            node = Sdr.Registry().GetNodeByIdentifier(sdrIdentifier, ['USD'])
            self.assertTrue(node is not None)
            self.assertIn(sdrIdentifier, expectedLightNodes)

            # Names, identifier, and role for the node all match the USD schema
            # type name
            self.assertEqual(node.GetIdentifier(), sdrIdentifier)
            self.assertEqual(node.GetName(), sdrIdentifier)
            self.assertEqual(node.GetImplementationName(), sdrIdentifier)
            self.assertEqual(node.GetRole(), sdrIdentifier)
            self.assertTrue(node.GetInfoString().startswith(sdrIdentifier))

            # The context is always 'light' for lights. 
            # Source type is 'USD'
            self.assertEqual(node.GetContext(), 'light')
            self.assertEqual(node.GetSourceType(), 'USD')

            # Help string is generated and encoded in the node's metadata (no
            # need to verify the specific wording).
            self.assertTrue(set(node.GetMetadata().keys()), {'primvars', 'help'})
            self.assertEqual(node.GetMetadata()["help"], node.GetHelp())

            # Source code and URIs are all empty.
            self.assertFalse(node.GetSourceCode())
            self.assertFalse(node.GetResolvedDefinitionURI())
            self.assertFalse(node.GetResolvedImplementationURI())

            # Other classifications are left empty.
            self.assertFalse(node.GetCategory())
            self.assertFalse(node.GetDepartments())
            self.assertFalse(node.GetFamily())
            self.assertFalse(node.GetLabel())
            self.assertFalse(node.GetVersion())
            self.assertFalse(node.GetAllVstructNames())
            self.assertEqual(node.GetPages(), [''])

            # The node will be valid for our light types.
            self.assertTrue(node.IsValid())

            # Helper for comparing an SdrShaderProperty from node to the 
            # corresponding UsdShadeInput/UsdShadeOutput from a UsdLux light
            def _CompareLightPropToNodeProp(nodeInput, primInput):
                # Input names and default values match.
                primDefaultValue = primInput.GetAttr().Get()
                self.assertEqual(nodeInput.GetName(), primInput.GetBaseName())
                self.assertEqual(nodeInput.GetDefaultValue(), primDefaultValue)

                # Some USD property types don't match exactly one to one and are
                # converted to different types. In particular relevance to 
                # lights and Token becomes String.
                expectedTypeName = primInput.GetTypeName()
                # Array valued attributes have their array size determined from
                # the default value and will be converted to scalar in the 
                # SdrProperty if the array size is zero.
                if expectedTypeName.isArray:
                    if not primDefaultValue or len(primDefaultValue) == 0:
                        expectedTypeName = expectedTypeName.scalarType
                elif expectedTypeName == Sdf.ValueTypeNames.Token:
                    expectedTypeName = Sdf.ValueTypeNames.String 
                # Bool SdfTypes should Have Int SdrTypes, but still return as
                # Bool when queried for GetTypeAsSdfType
                if expectedTypeName == Sdf.ValueTypeNames.Bool:
                    self.assertEqual(nodeInput.GetType(),
                            Sdf.ValueTypeNames.Int)
                # Verify the node's input type maps back to USD property's type
                # (with the noted above exceptions).
                self.assertEqual(
                    nodeInput.GetTypeAsSdfType()[0], expectedTypeName,
                    msg="{}.{} Type {} != {}".format(
                        str(node.GetName()),
                        str(nodeInput.GetName()),
                        str(nodeInput.GetTypeAsSdfType()[0]),
                        str(expectedTypeName)))
                # If the USD property type is an Asset, it will be listed in 
                # the node's asset identifier inputs.
                if expectedTypeName == Sdf.ValueTypeNames.Asset:
                    self.assertIn(nodeInput.GetName(), 
                                  node.GetAssetIdentifierInputNames())

            # There will be a one to one correspondence between node inputs
            # and prim inputs. Note that the prim may have additional inputs
            # because of auto applied API schemas, but we only need to verify
            # that the node has ONLY the expected inputs and the prim at least
            # has those input proerties.
            expectedInputNames = \
                expectedLightInputNames + expectedLightNodes[sdrIdentifier]
            # Verify node has exactly the expected inputs.
            self.assertEqual(sorted(expectedInputNames),
                             sorted(node.GetInputNames()))
            # Verify each node input matches a prim input.
            for inputName in expectedInputNames:
                nodeInput = node.GetInput(inputName)
                primInput = light.GetInput(inputName)
                self.assertFalse(nodeInput.IsOutput())
                _CompareLightPropToNodeProp(nodeInput, primInput)

            # None of the UsdLux base lights have outputs
            self.assertEqual(node.GetOutputNames(), [])
            self.assertEqual(light.GetOutputs(onlyAuthored=False), [])

            # The reverse is tested just above, but for all asset identifier
            # inputs listed for the node there is a corresponding asset value
            # input property on the prim.
            for inputName in node.GetAssetIdentifierInputNames():
                self.assertEqual(light.GetInput(inputName).GetTypeName(),
                                 Sdf.ValueTypeNames.Asset)

            # These primvars come from sdrMetadata on the prim itself which
            # isn't supported for light schemas so it will always be empty.
            self.assertFalse(node.GetPrimvars())
            # sdrMetadata on input properties is supported so additional 
            # primvar properties will correspond to prim inputs with that 
            # metadata set.
            for propName in node.GetAdditionalPrimvarProperties():
                self.assertTrue(light.GetInput(propName).GetSdrMetadataByKey(
                    'primvarProperty'))

            # Default input can also be specified in the property's sdrMetadata.
            if node.GetDefaultInput():
                defaultInput = light.GetInput(
                    node.GetDefaultInput().GetName())
                self.assertTrue(defaultInput.GetSdrMetadataByKey('defaultInput'))
Exemple #21
0
    def _ValidateUsdLuxLight(self, lightTypeName):
        primPathFormat = '/RfMLightsTest/Lights/%s'

        lightPrimPath = primPathFormat % lightTypeName
        lightPrim = self._stage.GetPrimAtPath(lightPrimPath)
        self.assertTrue(lightPrim)

        testNumber = None
        if lightTypeName == 'DiskLight':
            self.assertTrue(lightPrim.IsA(UsdLux.DiskLight))
            testNumber = 1
        elif lightTypeName == 'DistantLight':
            self.assertTrue(lightPrim.IsA(UsdLux.DistantLight))
            testNumber = 2
        elif lightTypeName == 'DomeLight':
            self.assertTrue(lightPrim.IsA(UsdLux.DomeLight))
            testNumber = 3
        elif lightTypeName == 'MeshLight':
            self.assertTrue(lightPrim.IsA(UsdLux.GeometryLight))
            testNumber = 4
        elif lightTypeName == 'RectLight':
            self.assertTrue(lightPrim.IsA(UsdLux.RectLight))
            testNumber = 5
        elif lightTypeName == 'SphereLight':
            self.assertTrue(lightPrim.IsA(UsdLux.SphereLight))
            testNumber = 6
        elif lightTypeName == 'AovLight':
            self.assertTrue(lightPrim.IsA(UsdRi.PxrAovLight))
            testNumber = 7
        elif lightTypeName == 'EnvDayLight':
            self.assertTrue(lightPrim.IsA(UsdRi.PxrEnvDayLight))
            testNumber = 8
        else:
            raise NotImplementedError('Invalid light type %s' % lightTypeName)

        lightSchema = UsdLux.Light(lightPrim)
        self.assertTrue(lightSchema)

        if lightTypeName == 'AovLight':
            # PxrAovLight doesn't have any of the below attributes.
            return

        expectedIntensity = 1.0 + (testNumber * 0.1)
        self.assertTrue(Gf.IsClose(lightSchema.GetIntensityAttr().Get(),
            expectedIntensity, 1e-6))

        expectedExposure = 0.1 * testNumber
        self.assertTrue(Gf.IsClose(lightSchema.GetExposureAttr().Get(),
            expectedExposure, 1e-6))

        expectedDiffuse = 1.0 + (testNumber * 0.1)
        self.assertTrue(Gf.IsClose(lightSchema.GetDiffuseAttr().Get(),
            expectedDiffuse, 1e-6))

        expectedSpecular = 1.0 + (testNumber * 0.1)
        self.assertTrue(Gf.IsClose(lightSchema.GetSpecularAttr().Get(),
            expectedSpecular, 1e-6))

        if lightTypeName == 'EnvDayLight':
            # PxrEnvDayLight doesn't have any of the below attributes.
            return

        if lightTypeName == 'DomeLight':
            # PxrDomeLight has no normalize attribute
            self.assertFalse(
                lightSchema.GetNormalizeAttr().HasAuthoredValueOpinion())
        else:
            expectedNormalize = True
            self.assertEqual(lightSchema.GetNormalizeAttr().Get(),
                expectedNormalize)

        expectedColor = Gf.Vec3f(0.1 * testNumber)
        self.assertTrue(Gf.IsClose(lightSchema.GetColorAttr().Get(),
            expectedColor, 1e-6))

        expectedEnableTemperature = True
        self.assertEqual(lightSchema.GetEnableColorTemperatureAttr().Get(),
            expectedEnableTemperature)

        expectedTemperature = 6500.0 + testNumber
        self.assertTrue(Gf.IsClose(lightSchema.GetColorTemperatureAttr().Get(),
            expectedTemperature, 1e-6))
Exemple #22
0
    def _test(self, stage):
        listAPI = UsdLux.ListAPI(stage.GetPrimAtPath('/World'))
        consult = UsdLux.ListAPI.ComputeModeConsultModelHierarchyCache
        ignore = UsdLux.ListAPI.ComputeModeIgnoreCache

        # no cache initially
        self.assertEqual(len(listAPI.GetLightListRel().GetTargets()), 0)
        # compute w/o cache should find 1 light outside payload
        computed_list = listAPI.ComputeLightList(ignore)
        self.assertEqual(len(computed_list), 1)
        self.assertTrue(Sdf.Path('/World/Lights/Sky_light') in computed_list)
        # compute w/ cache should find 1 extra light, since 1 light
        # inside a payload has been published to cache
        computed_list = listAPI.ComputeLightList(consult)
        self.assertEqual(len(computed_list), 2)
        self.assertTrue(Sdf.Path('/World/Lights/Sky_light') in computed_list)
        self.assertTrue(Sdf.Path('/World/Geo/torch_2/light') in computed_list)

        # load payloads to discover the rest of the lights
        stage.Load()
        # if we consult the cache we still won't see lights below model
        # hierarchy
        computed_list = listAPI.ComputeLightList(consult)
        self.assertEqual(len(computed_list), 2)
        self.assertTrue(Sdf.Path('/World/Lights/Sky_light') in computed_list)
        self.assertTrue(Sdf.Path('/World/Geo/torch_2/light') in computed_list)
        # but if we ignore cache we now see 3 lights
        computed_list = listAPI.ComputeLightList(ignore)
        self.assertEqual(len(computed_list), 3)
        self.assertTrue(Sdf.Path('/World/Lights/Sky_light') in computed_list)
        self.assertTrue(Sdf.Path('/World/Geo/torch_1/light') in computed_list)
        self.assertTrue(Sdf.Path('/World/Geo/torch_2/light') in computed_list)

        # store this full list in the light list
        listAPI.StoreLightList(computed_list)

        # now using the cache should return everything
        computed_list = listAPI.ComputeLightList(consult)
        self.assertEqual(len(computed_list), 3)
        self.assertTrue(Sdf.Path('/World/Lights/Sky_light') in computed_list)
        self.assertTrue(Sdf.Path('/World/Geo/torch_1/light') in computed_list)
        self.assertTrue(Sdf.Path('/World/Geo/torch_2/light') in computed_list)

        # deactivate 1 torch model
        torch_1 = stage.GetPrimAtPath('/World/Geo/torch_1')
        torch_1.SetActive(False)

        # if we ignore the cache(s) we do see only 2 lights
        self.assertEqual(len(listAPI.ComputeLightList(ignore)), 2)
        # but the cache should continue to report 3 lights
        self.assertEqual(len(listAPI.ComputeLightList(consult)), 3)
        # invalidating the cache should cause it to report 2 lights
        listAPI.InvalidateLightList()
        self.assertEqual(len(listAPI.ComputeLightList(consult)), 2)

        # add a light filter, and confirm that it gets included as a light
        self.assertEqual(len(listAPI.ComputeLightList(ignore)), 2)
        filter = UsdLux.LightFilter.Define(stage, '/World/Lights/TestFilter')
        self.assertEqual(len(listAPI.ComputeLightList(ignore)), 3)

        # add an untyped prim and apply a LightAPI. Confirm that it also gets
        # included as a light.
        self.assertEqual(len(listAPI.ComputeLightList(ignore)), 3)
        prim = stage.DefinePrim("/World/Lights/PrimWithLightAPI")
        self.assertEqual(len(listAPI.ComputeLightList(ignore)), 3)
        UsdLux.LightAPI.Apply(prim)
        self.assertEqual(len(listAPI.ComputeLightList(ignore)), 4)

        # discard changes
        stage.Reload()