Esempio n. 1
0
    def test_FindAppliedAPIPrimDefinition(self):
        # CollectionAPI is an applied API schama. Can get the prim definition
        # through FindAppliedAPIPrimDefintion.
        primDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition(
            'CollectionAPI')
        self.assertTrue(primDef)

        # Prim def has built in property names.
        self.assertEqual(
            primDef.GetPropertyNames(),
            ['expansionRule', 'includeRoot', 'excludes', 'includes'])

        # Prim def has relationship/property spec for 'excludes'
        self.assertTrue(primDef.GetSchemaPropertySpec('excludes'))
        self.assertFalse(primDef.GetSchemaAttributeSpec('excludes'))
        self.assertTrue(primDef.GetSchemaRelationshipSpec('excludes'))

        # Prim def has attribute/property spec for 'expansionRule'.
        self.assertTrue(primDef.GetSchemaPropertySpec('expansionRule'))
        self.assertTrue(primDef.GetSchemaAttributeSpec('expansionRule'))
        self.assertFalse(primDef.GetSchemaRelationshipSpec('expansionRule'))

        # API schema but not an applied schema. No prim definition
        self.assertFalse(
            Usd.SchemaRegistry().FindAppliedAPIPrimDefinition('ModelAPI'))
        # Concrete typed schema. Not returned from FindAppliedAPI...
        self.assertFalse(
            Usd.SchemaRegistry().FindAppliedAPIPrimDefinition('MetadataTest'))
Esempio n. 2
0
    def test_FindConcretePrimDefinition(self):
        # MetadataTest is a concrete prim schama. Can get the prim definition
        # through FindConcretePrimDefinition.
        primDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            'MetadataTest')
        self.assertTrue(primDef)

        # Prim def has built in property names.
        self.assertEqual(primDef.GetPropertyNames(), ['testAttr', 'testRel'])

        # Prim def has relationship/property spec for 'testRel'
        self.assertTrue(primDef.GetSchemaPropertySpec('testRel'))
        self.assertFalse(primDef.GetSchemaAttributeSpec('testRel'))
        self.assertTrue(primDef.GetSchemaRelationshipSpec('testRel'))

        # Prim def has attribute/property spec for 'testAttr'.
        self.assertTrue(primDef.GetSchemaPropertySpec('testAttr'))
        self.assertTrue(primDef.GetSchemaAttributeSpec('testAttr'))
        self.assertFalse(primDef.GetSchemaRelationshipSpec('testAttr'))

        # Non-apply API schema. No prim definition
        self.assertFalse(
            Usd.SchemaRegistry().FindConcretePrimDefinition('ModelAPI'))
        # Applied API schema. Not returned from FindConcretePrimDefinition
        self.assertFalse(
            Usd.SchemaRegistry().FindConcretePrimDefinition('CollectionAPI'))
Esempio n. 3
0
    def test_IsAppliedAPISchema(self):
        modelAPI = Tf.Type.FindByName("UsdModelAPI")
        clipsAPI = Tf.Type.FindByName("UsdClipsAPI")
        collectionAPI = Tf.Type.FindByName("UsdCollectionAPI")

        self.assertFalse(Usd.SchemaRegistry().IsAppliedAPISchema(modelAPI))
        self.assertFalse(Usd.SchemaRegistry().IsAppliedAPISchema(clipsAPI))
        self.assertTrue(Usd.SchemaRegistry().IsAppliedAPISchema(collectionAPI))
Esempio n. 4
0
    def test_IsConcrete(self):
        modelAPI = Tf.Type.FindByName("UsdModelAPI")
        clipsAPI = Tf.Type.FindByName("UsdClipsAPI")
        collectionAPI = Tf.Type.FindByName("UsdCollectionAPI")

        self.assertFalse(Usd.SchemaRegistry().IsConcrete(modelAPI))
        self.assertFalse(Usd.SchemaRegistry().IsConcrete(clipsAPI))
        self.assertFalse(Usd.SchemaRegistry().IsConcrete(collectionAPI))
Esempio n. 5
0
    def test_FindAppliedAPIPrimDefinition(self):
        # CollectionAPI is an applied API schama. Can get the prim definition
        # through FindAppliedAPIPrimDefintion.
        primDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition(
            'CollectionAPI')
        self.assertTrue(primDef)

        # Prim def has built in property names.
        self.assertEqual(primDef.GetPropertyNames(), [
            'collection:__INSTANCE_NAME__:expansionRule',
            'collection:__INSTANCE_NAME__:includeRoot',
            'collection:__INSTANCE_NAME__:excludes',
            'collection:__INSTANCE_NAME__:includes'
        ])

        # Prim def has relationship/property spec for 'excludes'
        self.assertTrue(
            primDef.GetSchemaPropertySpec(
                'collection:__INSTANCE_NAME__:excludes'))
        self.assertFalse(
            primDef.GetSchemaAttributeSpec(
                'collection:__INSTANCE_NAME__:excludes'))
        self.assertTrue(
            primDef.GetSchemaRelationshipSpec(
                'collection:__INSTANCE_NAME__:excludes'))

        # Prim def has attribute/property spec for 'expansionRule'.
        self.assertTrue(
            primDef.GetSchemaPropertySpec(
                'collection:__INSTANCE_NAME__:expansionRule'))
        self.assertTrue(
            primDef.GetSchemaAttributeSpec(
                'collection:__INSTANCE_NAME__:expansionRule'))
        self.assertFalse(
            primDef.GetSchemaRelationshipSpec(
                'collection:__INSTANCE_NAME__:expansionRule'))

        # We can also get the CollectionAPI prim definition using its template
        # name instead.
        templatePrimDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition(
            'CollectionAPI:__INSTANCE_NAME__')
        # Note that we can't test for equality of the prim defs directly, even
        # though they're the same, since the python objects are different. So we
        # verify that the main aspects of the definitions are same instead.
        self.assertEqual(templatePrimDef.GetPropertyNames(),
                         primDef.GetPropertyNames())
        self.assertEqual(templatePrimDef.ListMetadataFields(),
                         primDef.ListMetadataFields())
        self.assertEqual(templatePrimDef.GetAppliedAPISchemas(),
                         primDef.GetAppliedAPISchemas())

        # API schema but not an applied schema. No prim definition
        self.assertFalse(
            Usd.SchemaRegistry().FindAppliedAPIPrimDefinition('ModelAPI'))
        # Concrete typed schema. Not returned from FindAppliedAPI...
        self.assertFalse(
            Usd.SchemaRegistry().FindAppliedAPIPrimDefinition('MetadataTest'))
Esempio n. 6
0
    def test_Concrete(self):
        from pxr import Tf
        xform = Tf.Type.FindByName("UsdGeomXform")
        imageable = Tf.Type.FindByName("UsdGeomImageable")
        geomModelAPI = Tf.Type.FindByName("UsdGeomModelAPI")

        self.assertTrue(Usd.SchemaRegistry().IsConcrete(xform))
        self.assertFalse(Usd.SchemaRegistry().IsConcrete(imageable))
        self.assertFalse(Usd.SchemaRegistry().IsConcrete(geomModelAPI))
Esempio n. 7
0
 def test_GetPropertyNamespacePrefix(self):
     # CollectionAPI is a multiple apply API so it must have a property
     # namespace prefix.
     self.assertEqual(
         Usd.SchemaRegistry().GetPropertyNamespacePrefix("CollectionAPI"),
         "collection")
     # Other schema types that are not multiple apply API will not have a 
     # property namespace prefix.
     self.assertEqual(
         Usd.SchemaRegistry().GetPropertyNamespacePrefix("MetadataTest"), "")
     self.assertEqual(
         Usd.SchemaRegistry().GetPropertyNamespacePrefix("ClipsAPI"), "")
Esempio n. 8
0
    def buildUI(self):
        usdSch = Usd.SchemaRegistry()

        self.suppressArrayAttribute()

        # We use UFE for the ancestor node types since it caches the
        # results by node type.
        for schemaType in self.item.ancestorNodeTypes():
            schemaType = usdSch.GetTypeFromName(schemaType)
            schemaTypeName = schemaType.typeName
            sectionName = self.sectionNameFromSchema(schemaTypeName)
            if schemaType.pythonClass:
                attrsToAdd = schemaType.pythonClass.GetSchemaAttributeNames(
                    False)

                # We have a special case when building the Xformable section.
                if schemaTypeName == 'UsdGeomXformable':
                    self.createTransformAttributesSection(
                        sectionName, attrsToAdd)
                else:
                    sectionsToCollapse = [
                        'Curves', 'Point Based', 'Geometric Prim', 'Boundable',
                        'Imageable', 'Field Asset', 'Light'
                    ]
                    collapse = sectionName in sectionsToCollapse
                    self.createSection(sectionName, attrsToAdd, collapse)
Esempio n. 9
0
    def test_RelationshipMetadata(self):
        primDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            "MetadataTest")

        self.assertEqual(set(primDef.ListPropertyMetadataFields("testRel")), 
            set(["displayGroup", "displayName", "documentation", "hidden", 
                 "testCustomMetadata", "variability"]))
        self.assertEqual(primDef.GetPropertyMetadata("testRel", "displayGroup"), 
                         "Display Group")
        self.assertEqual(primDef.GetPropertyMetadata("testRel", "displayName"), 
                         "Display Name")
        self.assertEqual(primDef.GetPropertyMetadata("testRel", "documentation"),
                         "Testing documentation metadata")
        self.assertEqual(primDef.GetPropertyMetadata("testRel", "hidden"), 
                         True)
        self.assertEqual(primDef.GetPropertyMetadata("testRel", "testCustomMetadata"), 
                         "garply")
        self.assertEqual(primDef.GetPropertyMetadata("testRel", "variability"), 
                         Sdf.VariabilityUniform)

        self.assertIsNone(primDef.GetAttributeFallbackValue("testRel"))
        self.assertEqual(primDef.GetPropertyDocumentation("testRel"),
                         "Testing documentation metadata")

        relDef = primDef.GetSchemaRelationshipSpec("testRel")
        self.assertTrue(relDef)

        self.assertEqual(relDef.GetInfo("displayGroup"), "Display Group")
        self.assertEqual(relDef.GetInfo("displayName"), "Display Name")
        self.assertEqual(relDef.GetInfo("documentation"),
                         "Testing documentation metadata")
        self.assertEqual(relDef.GetInfo("hidden"), True)
        self.assertEqual(relDef.GetInfo("testCustomMetadata"), "garply")
Esempio n. 10
0
    def test_GetUsdSchemaTypeName(self):
        modelAPI = Tf.Type.FindByName("UsdModelAPI")
        clipsAPI = Tf.Type.FindByName("UsdClipsAPI")
        collectionAPI = Tf.Type.FindByName("UsdCollectionAPI")

        self.assertEqual(Usd.SchemaRegistry().GetSchemaTypeName(modelAPI),
                         "ModelAPI")
        self.assertEqual(Usd.SchemaRegistry().GetSchemaTypeName(clipsAPI),
                         "ClipsAPI")
        self.assertEqual(Usd.SchemaRegistry().GetSchemaTypeName(collectionAPI),
                         "CollectionAPI")

        # A valid type without an associated schema prim definition returns an
        # empty type name.
        self.assertTrue(Tf.Type(Usd.Typed))
        self.assertEqual(
            Usd.SchemaRegistry().GetSchemaTypeName(Tf.Type(Usd.Typed)), "")
Esempio n. 11
0
    def testCustomRigSchema(self):
        "Validate that codeless schema was discovered and loaded successfully"
        primDef = Usd.SchemaRegistry().FindConcretePrimDefinition("CustomRig")
        self.assertTrue(primDef)

        type = Tf.Type.FindByName("MayaUsdSchemaTestRig")
        self.assertEqual(
            type, Usd.SchemaRegistry.GetTypeFromSchemaTypeName("CustomRig"))

        self.assertEqual(primDef.GetPropertyNames(), ["cubes"])

        layer = Sdf.Layer.CreateAnonymous(".usd")
        stage = Usd.Stage.Open(layer, Usd.Stage.LoadAll)
        typedPrim = stage.DefinePrim("/bob", "CustomRig")
        self.assertTrue(typedPrim)
Esempio n. 12
0
    def test_PrimMetadata(self):
        primDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            "MetadataTest")
        self.assertTrue(primDef)

        self.assertEqual(set(primDef.ListMetadataFields()), 
            set(["typeName", "testCustomMetadata", "hidden", "documentation"]))
        self.assertEqual(primDef.GetMetadata("typeName"), "MetadataTest")
        self.assertEqual(primDef.GetMetadata("documentation"),
                         "Testing documentation metadata")
        self.assertEqual(primDef.GetMetadata("hidden"), True)
        self.assertEqual(primDef.GetMetadata("testCustomMetadata"), "garply")

        self.assertEqual(primDef.GetDocumentation(),
                         "Testing documentation metadata")
Esempio n. 13
0
    def test_AttributeMetadata(self):
        primDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            "MetadataTest")

        self.assertEqual(
            set(primDef.ListPropertyMetadataFields("testAttr")),
            set([
                "allowedTokens", "custom", "default", "displayGroup",
                "displayName", "documentation", "hidden", "testCustomMetadata",
                "typeName", "variability"
            ]))
        self.assertEqual(primDef.GetPropertyMetadata("testAttr", "typeName"),
                         "string")
        self.assertEqual(
            primDef.GetPropertyMetadata("testAttr", "allowedTokens"),
            Vt.TokenArray(["bar", "baz"]))
        self.assertEqual(
            primDef.GetPropertyMetadata("testAttr", "displayGroup"),
            "Display Group")
        self.assertEqual(
            primDef.GetPropertyMetadata("testAttr", "displayName"),
            "Display Name")
        self.assertEqual(
            primDef.GetPropertyMetadata("testAttr", "documentation"),
            "Testing documentation metadata")
        self.assertEqual(primDef.GetPropertyMetadata("testAttr", "hidden"),
                         True)
        self.assertEqual(
            primDef.GetPropertyMetadata("testAttr", "testCustomMetadata"),
            "garply")
        self.assertEqual(primDef.GetPropertyMetadata("testAttr", "default"),
                         "foo")

        self.assertEqual(primDef.GetAttributeFallbackValue("testAttr"), "foo")
        self.assertEqual(primDef.GetPropertyDocumentation("testAttr"),
                         "Testing documentation metadata")

        attrDef = primDef.GetSchemaAttributeSpec("testAttr")
        self.assertTrue(attrDef)

        self.assertEqual(attrDef.GetInfo("allowedTokens"),
                         Vt.TokenArray(["bar", "baz"]))
        self.assertEqual(attrDef.GetInfo("displayGroup"), "Display Group")
        self.assertEqual(attrDef.GetInfo("displayName"), "Display Name")
        self.assertEqual(attrDef.GetInfo("documentation"),
                         "Testing documentation metadata")
        self.assertEqual(attrDef.GetInfo("hidden"), True)
        self.assertEqual(attrDef.GetInfo("testCustomMetadata"), "garply")
Esempio n. 14
0
    def buildUI(self, ufeSceneItem):
        usdSch = Usd.SchemaRegistry()

        # We use UFE for the ancestor node types since it caches the
        # results by node type.
        for schemaType in ufeSceneItem.ancestorNodeTypes():
            schemaType = usdSch.GetTypeFromName(schemaType)
            schemaTypeName = schemaType.typeName
            sectionName = self.sectionNameFromSchema(schemaTypeName)
            if schemaType.pythonClass:
                attrsToAdd = schemaType.pythonClass.GetSchemaAttributeNames(False)

                # We have a special case when building the Xformable section.
                if schemaTypeName == 'UsdGeomXformable':
                    self.createTransformAttributesSection(ufeSceneItem, sectionName, attrsToAdd)
                else:
                    self.createSection(sectionName, attrsToAdd)
Esempio n. 15
0
    def test_SimpleTypedSchemaPrimDefinition(self):
        """
        Tests the prim definition for a simple typed schema that has no
        fallback API schemas
        """
        primDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            "TestTypedSchema")
        self.assertTrue(primDef)
        self.assertEqual(primDef.GetPropertyNames(), ["testAttr", "testRel"])
        self.assertEqual(primDef.GetAppliedAPISchemas(), [])
        self.assertEqual(primDef.GetDocumentation(), "Testing typed schema")

        # Verify property specs for named properties.
        for propName in primDef.GetPropertyNames():
            self.assertTrue(primDef.GetSchemaPropertySpec(propName))

        # Verify the attribute spec and its fallback value and type
        testAttr = primDef.GetSchemaAttributeSpec("testAttr")
        self.assertEqual(testAttr.default, "foo")
        self.assertEqual(testAttr.typeName.cppTypeName, "std::string")

        # Verify the relationship spec
        self.assertTrue(primDef.GetSchemaRelationshipSpec("testRel"))
    def testMayaReferenceAttributes(self):
        layer = Sdf.Layer.CreateAnonymous()
        stageOut = Usd.Stage.Open(layer.identifier)

        primPath = Sdf.AssetPath('/MayaReference')
        mayaReferencePath = '/somewherenice/path.ma'
        mayaNamespace = 'nsp'

        primOut = stageOut.DefinePrim(primPath.path, 'MayaReference')
        self.assertTrue(primOut.IsValid())

        mayaReferenceOut = mayaUsdSchemas.MayaReference(primOut)
        self.assertTrue(mayaReferenceOut.GetPrim())
        if Usd.GetVersion() > (0, 20, 2):
            typeName = Usd.SchemaRegistry().GetSchemaTypeName(
                mayaReferenceOut._GetStaticTfType())
        else:
            typeName = mayaReferenceOut.GetSchemaClassPrimDefinition().typeName
        self.assertEqual(typeName, 'MayaReference')

        mayaReferenceAttr = primOut.CreateAttribute('mayaReference',
                                                    Sdf.ValueTypeNames.Asset)
        mayaReferenceAttr.Set(mayaReferencePath)

        mayaNamespaceAttr = primOut.CreateAttribute('mayaNamespace',
                                                    Sdf.ValueTypeNames.String)
        mayaNamespaceAttr.Set(mayaNamespace)

        stageIn = Usd.Stage.Open(stageOut.Flatten())
        primIn = stageIn.GetPrimAtPath(primPath.path)
        self.assertTrue(primIn.IsValid())

        mayaReferenceIn = mayaUsdSchemas.MayaReference(primIn)
        self.assertTrue(mayaReferenceIn.GetMayaReferenceAttr().Get(),
                        mayaReferencePath)
        self.assertTrue(mayaReferenceIn.GetMayaNamespaceAttr().Get(),
                        mayaNamespace)
Esempio n. 17
0
    def test_OpenLayerWithFallbackTypes(self):
        stage = Usd.Stage.Open("WithFallback.usda")
        self.assertTrue(stage)

        def _VerifyFallbacksInStageMetdata(typeName, expectedFallbacksList):
            fallbacks = stage.GetMetadataByDictKey("fallbackPrimTypes", typeName)
            if expectedFallbacksList is None:
                self.assertIsNone(fallbacks)
            else:
                self.assertEqual(fallbacks, Vt.TokenArray(expectedFallbacksList))

        emptyPrimDef = Usd.SchemaRegistry().GetEmptyPrimDefinition()
        validType1PrimDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            "ValidType_1")
        validType2PrimDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            "ValidType_2")

        def _VerifyPrimDefsSame(primDef1, primDef2):
            self.assertEqual(primDef1.GetAppliedAPISchemas(), 
                             primDef2.GetAppliedAPISchemas())
            self.assertEqual(primDef1.GetPropertyNames(), 
                             primDef2.GetPropertyNames())
            for propName in primDef1.GetPropertyNames():
                self.assertEqual(primDef1.GetSchemaPropertySpec(propName), 
                                 primDef2.GetSchemaPropertySpec(propName))
            self.assertEqual(primDef1.ListMetadataFields(), 
                             primDef2.ListMetadataFields())
            for fieldName in primDef1.ListMetadataFields():
                self.assertEqual(primDef1.GetMetadata(fieldName), 
                                 primDef2.GetMetadata(fieldName))

        # ValidPrim_1 : Has no fallbacks defined in metadata but its type name
        # is a valid schema so it doesn't matter. This is the most typical case.
        prim = stage.GetPrimAtPath("/ValidPrim_1")
        _VerifyFallbacksInStageMetdata("ValidType_1", None)
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "ValidType_1")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "ValidType_1")
        self.assertEqual(primTypeInfo.GetSchemaType(), self.validType1)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "ValidType_1")
        self.assertTrue(prim.IsA(self.validType1))
        self.assertTrue(prim.IsA(Usd.Typed))
        _VerifyPrimDefsSame(prim.GetPrimDefinition(), validType1PrimDef)

        # ValidPrim_2 : Has fallbacks defined in metadata but its type name
        # is a valid schema, so it ignores fallbacks.
        prim = stage.GetPrimAtPath("/ValidPrim_2")
        _VerifyFallbacksInStageMetdata("ValidType_2", ["ValidType_1"])
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "ValidType_2")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "ValidType_2")
        self.assertEqual(primTypeInfo.GetSchemaType(), self.validType2)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "ValidType_2")
        self.assertTrue(prim.IsA(self.validType2))
        self.assertTrue(prim.IsA(Usd.Typed))
        _VerifyPrimDefsSame(prim.GetPrimDefinition(), validType2PrimDef)

        # InvalidPrim_1 : Has no fallbacks defined in metadata and its type name
        # is not a valid schema. This will have an invalid schema type.
        prim = stage.GetPrimAtPath("/InvalidPrim_1")
        _VerifyFallbacksInStageMetdata("InvalidType_1", None)
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "InvalidType_1")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "InvalidType_1")
        self.assertEqual(primTypeInfo.GetSchemaType(), Tf.Type.Unknown)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "")
        self.assertFalse(prim.IsA(Usd.Typed))
        _VerifyPrimDefsSame(prim.GetPrimDefinition(), emptyPrimDef)

        # InvalidPrim_2 : This prim's type is not a valid schema type, but the
        # type has a single fallback defined in metadata which is a valid type.
        # This prim's schema type will be this fallback type.
        prim = stage.GetPrimAtPath("/InvalidPrim_2")
        _VerifyFallbacksInStageMetdata("InvalidType_2", ["ValidType_2"])
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "InvalidType_2")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "InvalidType_2")
        self.assertEqual(primTypeInfo.GetSchemaType(), self.validType2)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "ValidType_2")
        self.assertTrue(prim.IsA(self.validType2))
        self.assertTrue(prim.IsA(Usd.Typed))
        _VerifyPrimDefsSame(prim.GetPrimDefinition(), validType2PrimDef)

        # InvalidPrim_3 : This prim's type is not a valid schema type, but the
        # type has two fallbacks defined in metadata which are both valid types.
        # This prim's schema type will be the first fallback type in the list.
        prim = stage.GetPrimAtPath("/InvalidPrim_3")
        _VerifyFallbacksInStageMetdata("InvalidType_3", 
                                       ["ValidType_1", "ValidType_2"])
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "InvalidType_3")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "InvalidType_3")
        self.assertEqual(primTypeInfo.GetSchemaType(), self.validType1)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "ValidType_1")
        self.assertTrue(prim.IsA(self.validType1))
        self.assertTrue(prim.IsA(Usd.Typed))
        _VerifyPrimDefsSame(prim.GetPrimDefinition(), validType1PrimDef)

        # InvalidPrim_4 : This prim's type is not a valid schema type, but the
        # type has two fallbacks defined in metadata. The first fallback type
        # is itself invalid, but second is a valid type. This prim's schema type
        # will be the second fallback type in the list.
        prim = stage.GetPrimAtPath("/InvalidPrim_4")
        _VerifyFallbacksInStageMetdata("InvalidType_4", 
                                       ["InvalidType_3", "ValidType_2"])
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "InvalidType_4")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "InvalidType_4")
        self.assertEqual(primTypeInfo.GetSchemaType(), self.validType2)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "ValidType_2")
        self.assertTrue(prim.IsA(self.validType2))
        self.assertTrue(prim.IsA(Usd.Typed))
        _VerifyPrimDefsSame(prim.GetPrimDefinition(), validType2PrimDef)

        # InvalidPrim_5 : This prim's type is not a valid schema type, but the
        # type has two fallbacks defined in metadata. However, both of these 
        # types are also invalid types. This will have an invalid schema type.
        prim = stage.GetPrimAtPath("/InvalidPrim_5")
        _VerifyFallbacksInStageMetdata("InvalidType_5", 
                                       ["InvalidType_3", "InvalidType_2"])
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "InvalidType_5")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "InvalidType_5")
        self.assertEqual(primTypeInfo.GetSchemaType(), Tf.Type.Unknown)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "")
        self.assertFalse(prim.IsA(Usd.Typed))
        _VerifyPrimDefsSame(prim.GetPrimDefinition(), emptyPrimDef)

        # InvalidPrim_WithAPISchemas_1 : Has no fallbacks defined in metadata 
        # and its type name is not a valid schema. This will have an invalid 
        # schema type, but the API schemas will still be applied
        prim = stage.GetPrimAtPath("/InvalidPrim_WithAPISchemas_1")
        _VerifyFallbacksInStageMetdata("InvalidType_1", None)
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "InvalidType_1")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "InvalidType_1")
        self.assertEqual(primTypeInfo.GetSchemaType(), Tf.Type.Unknown)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "")
        self.assertEqual(primTypeInfo.GetAppliedAPISchemas(), 
                         ["CollectionAPI:foo"])
        self.assertFalse(prim.IsA(Usd.Typed))
        self.assertEqual(prim.GetAppliedSchemas(), ["CollectionAPI:foo"])

        # Create a new prim with an empty typename and the same API schemas
        # as the above. Verify that because these two prims have the same 
        # effective schema type and applied schemas, that they use the same
        # prim definition even though their type names differ.
        otherPrim = stage.DefinePrim("/EmptyWithCollection", "")
        Usd.CollectionAPI.Apply(otherPrim, "foo")
        otherPrimTypeInfo = otherPrim.GetPrimTypeInfo()
        self.assertNotEqual(otherPrim.GetTypeName(), prim.GetTypeName())
        self.assertNotEqual(otherPrimTypeInfo, primTypeInfo)
        self.assertEqual(otherPrimTypeInfo.GetSchemaTypeName(), 
                         primTypeInfo.GetSchemaTypeName())
        self.assertEqual(otherPrimTypeInfo.GetSchemaType(), 
                         primTypeInfo.GetSchemaType())
        self.assertEqual(otherPrim.GetAppliedSchemas(), 
                         prim.GetAppliedSchemas())
        _VerifyPrimDefsSame(otherPrim.GetPrimDefinition(), 
                             prim.GetPrimDefinition())

        # InvalidPrim_2 : This prim's type is not a valid schema type, but the
        # type has a single fallback defined in metadata which is a valid type.
        # This prim's schema type will be this fallback type and the API schemas
        # will be applied over the fallbacktype.
        prim = stage.GetPrimAtPath("/InvalidPrim_WithAPISchemas_2")
        _VerifyFallbacksInStageMetdata("InvalidType_2", ["ValidType_2"])
        self.assertTrue(prim)
        self.assertEqual(prim.GetTypeName(), "InvalidType_2")
        primTypeInfo = prim.GetPrimTypeInfo()
        self.assertEqual(primTypeInfo.GetTypeName(), "InvalidType_2")
        self.assertEqual(primTypeInfo.GetSchemaType(), self.validType2)
        self.assertEqual(primTypeInfo.GetSchemaTypeName(), "ValidType_2")
        self.assertEqual(primTypeInfo.GetAppliedAPISchemas(), 
                         ["CollectionAPI:foo"])
        self.assertTrue(prim.IsA(self.validType2))
        self.assertTrue(prim.IsA(Usd.Typed))
        self.assertEqual(prim.GetAppliedSchemas(), ["CollectionAPI:foo"])

        # Create a new prim using the fallback typename and the same API schemas
        # as the above. Verify that because these two prims have the same 
        # effective schema type and applied schemas, that they use the same
        # prim definition even though their type names differ.
        otherPrim = stage.DefinePrim("/Valid2WithCollection", "ValidType_2")
        Usd.CollectionAPI.Apply(otherPrim, "foo")
        otherPrimTypeInfo = otherPrim.GetPrimTypeInfo()
        self.assertNotEqual(otherPrim.GetTypeName(), prim.GetTypeName())
        self.assertNotEqual(otherPrimTypeInfo, primTypeInfo)
        self.assertEqual(otherPrimTypeInfo.GetSchemaTypeName(), 
                         primTypeInfo.GetSchemaTypeName())
        self.assertEqual(otherPrimTypeInfo.GetSchemaType(), 
                         primTypeInfo.GetSchemaType())
        self.assertEqual(otherPrim.GetAppliedSchemas(), 
                         prim.GetAppliedSchemas())
        _VerifyPrimDefsSame(otherPrim.GetPrimDefinition(), 
                             prim.GetPrimDefinition())
Esempio n. 18
0
    def test_GetUsdSchemaTypeName(self):
        abstractTest = Tf.Type.FindByName("TestUsdSchemaRegistryAbstractTest")
        concreteTest = Tf.Type.FindByName("TestUsdSchemaRegistryMetadataTest")
        modelAPI = Tf.Type.FindByName("UsdModelAPI")
        collectionAPI = Tf.Type.FindByName("UsdCollectionAPI")

        # Test getting a schema type name from a TfType for a concrete typed
        # schema.
        self.assertEqual(Usd.SchemaRegistry.GetSchemaTypeName(concreteTest),
                         "MetadataTest")
        self.assertEqual(
            Usd.SchemaRegistry.GetConcreteSchemaTypeName(concreteTest),
            "MetadataTest")
        self.assertEqual(Usd.SchemaRegistry.GetAPISchemaTypeName(concreteTest),
                         "")

        # Test the reverse of getting the TfType for concrete typed schema name.
        self.assertEqual(
            Usd.SchemaRegistry.GetTypeFromSchemaTypeName("MetadataTest"),
            concreteTest)
        self.assertEqual(
            Usd.SchemaRegistry.GetConcreteTypeFromSchemaTypeName(
                "MetadataTest"), concreteTest)
        self.assertEqual(
            Usd.SchemaRegistry.GetAPITypeFromSchemaTypeName("MetadataTest"),
            Tf.Type.Unknown)

        # Test getting a schema type name from a TfType for an abstract typed
        # schema.
        self.assertEqual(Usd.SchemaRegistry.GetSchemaTypeName(abstractTest),
                         "AbstractTest")
        self.assertEqual(
            Usd.SchemaRegistry.GetConcreteSchemaTypeName(abstractTest), "")
        self.assertEqual(Usd.SchemaRegistry.GetAPISchemaTypeName(abstractTest),
                         "")

        # Test the reverse of getting the TfType for abastract typed schema name.
        self.assertEqual(
            Usd.SchemaRegistry.GetTypeFromSchemaTypeName("AbstractTest"),
            abstractTest)
        self.assertEqual(
            Usd.SchemaRegistry.GetConcreteTypeFromSchemaTypeName(
                "AbstractTest"), Tf.Type.Unknown)
        self.assertEqual(
            Usd.SchemaRegistry.GetAPITypeFromSchemaTypeName("MetadataTest"),
            Tf.Type.Unknown)

        # Test getting a schema type name from a TfType for an applied API
        # schema.
        self.assertEqual(Usd.SchemaRegistry.GetSchemaTypeName(collectionAPI),
                         "CollectionAPI")
        self.assertEqual(
            Usd.SchemaRegistry.GetConcreteSchemaTypeName(collectionAPI), "")
        self.assertEqual(
            Usd.SchemaRegistry.GetAPISchemaTypeName(collectionAPI),
            "CollectionAPI")

        # Test the reverse of getting the TfType for an applied API schema name.
        self.assertEqual(
            Usd.SchemaRegistry.GetTypeFromSchemaTypeName("CollectionAPI"),
            collectionAPI)
        self.assertEqual(
            Usd.SchemaRegistry.GetConcreteTypeFromSchemaTypeName(
                "CollectionAPI"), Tf.Type.Unknown)
        self.assertEqual(
            Usd.SchemaRegistry.GetAPITypeFromSchemaTypeName("CollectionAPI"),
            collectionAPI)

        # Test getting a schema type name from a TfType for a non-apply API
        # schema. This is the same API as for applied API schemas but may change
        # in the future?
        self.assertEqual(Usd.SchemaRegistry.GetSchemaTypeName(modelAPI),
                         "ModelAPI")
        self.assertEqual(
            Usd.SchemaRegistry.GetConcreteSchemaTypeName(modelAPI), "")
        self.assertEqual(Usd.SchemaRegistry.GetAPISchemaTypeName(modelAPI),
                         "ModelAPI")

        # Test the reverse of getting the TfType for a non-apply API schema name
        self.assertEqual(
            Usd.SchemaRegistry.GetTypeFromSchemaTypeName("ModelAPI"), modelAPI)
        self.assertEqual(
            Usd.SchemaRegistry.GetConcreteTypeFromSchemaTypeName("ModelAPI"),
            Tf.Type.Unknown)
        self.assertEqual(
            Usd.SchemaRegistry.GetAPITypeFromSchemaTypeName("ModelAPI"),
            modelAPI)

        # A valid type without an associated schema prim definition returns an
        # empty type name.
        self.assertTrue(Tf.Type(Usd.Typed))
        self.assertEqual(
            Usd.SchemaRegistry().GetSchemaTypeName(Tf.Type(Usd.Typed)), "")
Esempio n. 19
0
    def test_Basic(self):
        l = Sdf.Layer.CreateAnonymous()
        stage = Usd.Stage.Open(l.identifier)

        p = stage.DefinePrim("/Mesh", "Mesh")
        self.assertTrue(p)

        mesh = UsdGeom.Mesh(p)
        self.assertTrue(mesh)
        self.assertTrue(mesh.GetPrim())
        self.assertTrue(not mesh.GetPointsAttr().Get(1))
        self.assertEqual(
            p.GetTypeName(),
            Usd.SchemaRegistry().GetSchemaTypeName(mesh._GetStaticTfType()))

        #
        # Make sure uniform access behaves as expected.
        #
        ori = p.GetAttribute("orientation")

        # The generic orientation attribute should be automatically defined because
        # it is a registered attribute of a well known schema.  However, it's not
        # yet authored at the current edit target.
        self.assertTrue(ori.IsDefined())
        self.assertTrue(not ori.IsAuthoredAt(ori.GetStage().GetEditTarget()))
        # Author a value, and check that it's still defined, and now is in fact
        # authored at the current edit target.
        ori.Set(UsdGeom.Tokens.leftHanded)
        self.assertTrue(ori.IsDefined())
        self.assertTrue(ori.IsAuthoredAt(ori.GetStage().GetEditTarget()))
        mesh.GetOrientationAttr().Set(UsdGeom.Tokens.rightHanded, 10)

        # "leftHanded" should have been authored at Usd.TimeCode.Default, so reading the
        # attribute at Default should return lh, not rh.
        self.assertEqual(ori.Get(), UsdGeom.Tokens.leftHanded)

        # The value "rightHanded" was set at t=10, so reading *any* time should
        # return "rightHanded"
        self.assertEqual(ori.Get(9.9), UsdGeom.Tokens.rightHanded)
        self.assertEqual(ori.Get(10), UsdGeom.Tokens.rightHanded)
        self.assertEqual(ori.Get(10.1), UsdGeom.Tokens.rightHanded)
        self.assertEqual(ori.Get(11), UsdGeom.Tokens.rightHanded)

        #
        # Attribute name sanity check. We expect the names returned by the schema
        # to match the names returned via the generic API.
        #
        self.assertTrue(len(mesh.GetSchemaAttributeNames()) > 0)
        self.assertNotEqual(mesh.GetSchemaAttributeNames(True),
                            mesh.GetSchemaAttributeNames(False))

        for n in mesh.GetSchemaAttributeNames():
            # apiName overrides
            if n == "primvars:displayColor":
                n = "displayColor"
            elif n == "primvars:displayOpacity":
                n = "displayOpacity"

            name = n[0].upper() + n[1:]
            self.assertTrue(
                ("Get" + name + "Attr") in dir(mesh),
                ("Get" + name + "Attr() not found in: " + str(dir(mesh))))
Esempio n. 20
0
def UpdateSchemaWithSdrNode(schemaLayer,
                            sdrNode,
                            renderContext="",
                            overrideIdentifier=""):
    """
    Updates the given schemaLayer with primSpec and propertySpecs from sdrNode
    metadata. 

    A renderContext can be provided which is used in determining the
    shaderId namespace, which follows the pattern: 
    "<renderContext>:<SdrShaderNodeContext>:shaderId". Note that we are using a
    node's context (SDR_NODE_CONTEXT_TOKENS) here to construct the shaderId
    namespace, so shader parsers should make sure to use appropriate
    SDR_NODE_CONTEXT_TOKENS in the node definitions.

    overrideIdentifier parameter is the identifier which should be used when 
    the identifier of the node being processed differs from the one Sdr will 
    discover at runtime, such as when this function is def a node constructed 
    from an explicit asset path. This should only be used when clients know the 
    identifier being passed is the true identifier which sdr Runtime will 
    provide when querying using GetShaderNodeByNameAndType, etc.

    It consumes the following attributes (that manifest as Sdr 
    metadata) in addition to many of the standard Sdr metadata
    specified and parsed (via its parser plugin).

    Node Level Metadata:
        - "schemaName": Name of the new schema populated from the given sdrNode
          (Required)
        - "schemaKind": Specifies the UsdSchemaKind for the schema being
          populated from the sdrNode. (Note that this does not support
          multiple apply schema kinds).
        - "schemaBase": Base schema from which the new schema should inherit
          from. Note this defaults to "APISchemaBase" for an API schema or 
          "Typed" for a concrete scheme.
        - "usdSchemaClass": Specifies the equivalent schema directly generated
          by USD (sourceType: USD). This is used to make sure duplicate
          properties already specified in the USD schema are not populated in
          the new API schema. Note this is only used when we are dealing with an
          API schema.
        - "apiSchemaAutoApplyTo": The schemas to which the sdrNode populated 
          API schema will autoApply to.
        - "apiSchemaCanOnlyApplyTo": If specified, the API schema generated 
          from the sdrNode can only be validly applied to this set of schemas.
        - "providesUsdShadeConnectableAPIBehavior": Used to enable a 
          connectability behavior for an API schema.
        - "isUsdShadeContainer": Only used when
          providesUsdShadeConnectableAPIBehavior is set to true. Marks the
          connectable prim as a UsdShade container type.
        - "requiresUsdShadeEncapsulation": Only used when
          providesUsdShadeConnectableAPIBehavior is set to true. Configures the
          UsdShade encapsulation rules governing its connectableBehavior.
        - "tfTypeNameSuffix": Class name which will get registered with TfType 
          system. This gets appended to the domain name to register with TfType.

    Property Level Metadata:
        - USD_VARIABILITY: Property level metadata which specifies a specific 
          sdrNodeProperty should have its USD variability set to Uniform or 
          Varying
        - USD_SUPPRESS_PROPERTY: A property level metadata which determines if 
          the property should be suppressed from translation from args to 
          property spec.

    Sdr Property Metadata to SdfPropertySpec Translations
        - A "null" value for Widget sdrProperty metadata translates to 
          SdfPropertySpec Hidden metadata.
        - SdrProperty's Help metadata (Label metadata if Help metadata not 
          provided) translates to SdfPropertySpec's Documentation string 
          metadata.
        - SdrProperty's Page metadata translates to SdfPropertySpec's
          DisplayGroup metadata.
        - SdrProperty's Label metadata translates to SdfPropertySpec's
          DisplayName metadata.
        - SdrProperty's Options translates to SdfPropertySpec's AllowedTokens.
        - SdrProperty's Default value translates to SdfPropertySpec's Default
          value.
        - Connectable input properties translates to InterfaceOnly
          SdfPropertySpec's CONNECTABILITY.
    """

    import distutils.util
    import os

    # Early exit on invalid parameters
    if not schemaLayer:
        Tf.Warn("No Schema Layer provided")
        return
    if not sdrNode:
        Tf.Warn("No valid sdrNode provided")
        return

    sdrNodeMetadata = sdrNode.GetMetadata()

    if SchemaDefiningKeys.SCHEMA_NAME not in sdrNodeMetadata:
        Tf.Warn("Sdr Node (%s) does not define a schema name metadata." \
                %(sdrNode.GetName()))
        return
    schemaName = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_NAME]
    if not Tf.IsValidIdentifier(schemaName):
        Tf.RaiseRuntimeError(
            "schemaName (%s) is an invalid identifier; "
            "Provide a valid USD identifer for schemaName, example (%s) " %
            (schemaName, Tf.MakeValidIdentifier(schemaName)))

    tfTypeNameSuffix = None
    if SchemaDefiningKeys.TF_TYPENAME_SUFFIX in sdrNodeMetadata:
        tfTypeNameSuffix = sdrNodeMetadata[
            SchemaDefiningKeys.TF_TYPENAME_SUFFIX]
        if not Tf.IsValidIdentifier(tfTypeNameSuffix):
            Tf.RaiseRuntimeError("tfTypeNameSuffix (%s) is an invalid " \
                    "identifier" %(tfTypeNameSuffix))

    if SchemaDefiningKeys.SCHEMA_KIND not in sdrNodeMetadata:
        schemaKind = SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaKind = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_KIND]

    # Note: We are not working on dynamic multiple apply schemas right now.
    isAPI = schemaKind == SchemaDefiningMiscConstants.SINGLE_APPLY_SCHEMA
    # Fix schemaName and warn if needed
    if isAPI and \
        not schemaName.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created is "
                "an API schema, fixing schemaName to reflect that")
        schemaName = schemaName + SchemaDefiningMiscConstants.API_STRING

    if isAPI and tfTypeNameSuffix and \
        not tfTypeNameSuffix.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created "
                "is an API schema, fixing tfTypeNameSuffix to reflect that")
        tfTypeNameSuffix = tfTypeNameSuffix + \
                SchemaDefiningMiscConstants.API_STRING

    if SchemaDefiningKeys.SCHEMA_BASE not in sdrNodeMetadata:
        Tf.Warn("No schemaBase specified in node metadata, defaulting to "
                "APISchemaBase for API schemas else Typed")
        schemaBase = SchemaDefiningMiscConstants.API_SCHEMA_BASE if isAPI \
                else SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaBase = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_BASE]

    apiSchemaAutoApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO in sdrNodeMetadata:
        apiSchemaAutoApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO] \
                .split('|')

    apiSchemaCanOnlyApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_CAN_ONLY_APPLY_TO in sdrNodeMetadata:
        apiSchemaCanOnlyApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_CAN_ONLY_APPLY_TO] \
                .split('|')

    providesUsdShadeConnectableAPIBehavior = False
    if SchemaDefiningKeys.PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR in \
            sdrNodeMetadata:
        providesUsdShadeConnectableAPIBehavior = \
            distutils.util.strtobool(sdrNodeMetadata[SchemaDefiningKeys. \
                PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR])

    usdSchemaClass = None
    if isAPI and SchemaDefiningKeys.USD_SCHEMA_CLASS in sdrNodeMetadata:
        usdSchemaClass = \
            sdrNodeMetadata[SchemaDefiningKeys.USD_SCHEMA_CLASS]

    primSpec = schemaLayer.GetPrimAtPath(schemaName)

    if (primSpec):
        # if primSpec already exist, remove entirely and recreate using the
        # parsed sdr node
        if primSpec.nameParent:
            del primSpec.nameParent.nameChildren[primSpec.name]
        else:
            del primSpec.nameRoot.nameChildren[primSpec.name]

    primSpec = Sdf.PrimSpec(schemaLayer, schemaName, Sdf.SpecifierClass,
                            "" if isAPI else schemaName)

    primSpec.inheritPathList.explicitItems = ["/" + schemaBase]

    primSpecCustomData = {}
    if isAPI:
        primSpecCustomData["apiSchemaType"] = schemaKind
    if tfTypeNameSuffix:
        # Defines this classname for TfType system
        # can help avoid duplicate prefix with domain and className
        # Tf type system will automatically pick schemaName as tfTypeName if
        # this is not set!
        primSpecCustomData["className"] = tfTypeNameSuffix

    if apiSchemaAutoApplyTo:
        primSpecCustomData['apiSchemaAutoApplyTo'] = \
            Vt.TokenArray(apiSchemaAutoApplyTo)
    if apiSchemaCanOnlyApplyTo:
        primSpecCustomData['apiSchemaCanOnlyApplyTo'] = \
            Vt.TokenArray(apiSchemaCanOnlyApplyTo)

    if providesUsdShadeConnectableAPIBehavior:
        extraPlugInfo = {
            SchemaDefiningKeys.PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR \
                    : True
        }
        for propKey in [SchemaDefiningKeys.IS_USD_SHADE_CONTAINER, \
                SchemaDefiningKeys.REQUIRES_USD_SHADE_ENCAPSULATION]:
            if propKey in sdrNodeMetadata:
                # Since we want to assign the types for these to bool and
                # because in python boolean type is a subset of int, we need to
                # do following instead of assign the propValue directly.
                propValue = distutils.util.strtobool(sdrNodeMetadata[propKey])
                extraPlugInfo[propKey] = bool(propValue)

        primSpecCustomData['extraPlugInfo'] = extraPlugInfo

    primSpec.customData = primSpecCustomData

    doc = sdrNode.GetHelp()
    if doc != "":
        primSpec.documentation = doc

    # gather properties from node directly generated from USD (sourceType: USD)
    # Use the usdSchemaClass tag when the generated schema being defined is an
    # API schema
    usdSchemaNode = None
    if usdSchemaClass:
        reg = Sdr.Registry()
        if usdSchemaClass.endswith(SchemaDefiningMiscConstants.API_STRING):
            # This usd schema is an API schema, we need to extract the shader
            # identifier from its primDef's shaderId field.
            primDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition(
                usdSchemaClass)
            if primDef:
                # We are dealing with USD source type here, hence no render
                # context is required but we can still borrow node context
                # information from the sdrNode in question, since the usd source
                # type node should also belong to the same context.
                shaderIdAttrName = Sdf.Path.JoinIdentifier( \
                        sdrNode.GetContext(), PropertyDefiningKeys.SHADER_ID)
                sdrIdentifier = primDef.GetAttributeFallbackValue(
                    shaderIdAttrName)
                if sdrIdentifier != "":
                    usdSchemaNode = reg.GetNodeByIdentifierAndType(
                        sdrIdentifier,
                        SchemaDefiningMiscConstants.USD_SOURCE_TYPE)
                else:
                    Tf.Warn("No sourceId authored for '%s'." %
                            (usdSchemaClass))
            else:
                Tf.Warn("Illegal API schema provided for the usdSchemaClass "
                        "metadata. No prim definition registered for '%s'" %
                        (usdSchemaClass))

        else:
            usdSchemaNode = reg.GetNodeByIdentifierAndType(
                usdSchemaClass, SchemaDefiningMiscConstants.USD_SOURCE_TYPE)

    # Create attrSpecs from input parameters
    for propName in sdrNode.GetInputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetInput(propName),
                                         usdSchemaNode)

    # Create attrSpecs from output parameters
    for propName in sdrNode.GetOutputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetOutput(propName),
                                         usdSchemaNode, False)

    # Create token shaderId attrSpec
    shaderIdAttrName = Sdf.Path.JoinIdentifier( \
            [renderContext, sdrNode.GetContext(), PropertyDefiningKeys.SHADER_ID])
    shaderIdAttrSpec = Sdf.AttributeSpec(primSpec, shaderIdAttrName,
                                         Sdf.ValueTypeNames.Token,
                                         Sdf.VariabilityUniform)

    # Since users shouldn't need to be aware of shaderId attribute, we put this
    # in "Internal" displayGroup.
    shaderIdAttrSpec.displayGroup = PropertyDefiningKeys.INTERNAL_DISPLAY_GROUP

    # Use the identifier if explicitly provided, (it could be a shader node
    # queried using an explicit path), else use sdrNode's registered identifier.
    nodeIdentifier = overrideIdentifier if overrideIdentifier else \
            sdrNode.GetIdentifier()
    shaderIdAttrSpec.default = nodeIdentifier

    # Extra attrSpec
    schemaBasePrimDefinition = \
        Usd.SchemaRegistry().FindConcretePrimDefinition(schemaBase)
    if schemaBasePrimDefinition and \
        SchemaDefiningMiscConstants.NodeDefAPI in \
        schemaBasePrimDefinition.GetAppliedAPISchemas():
        infoIdAttrSpec = Sdf.AttributeSpec(primSpec, \
                UsdShade.Tokens.infoId, Sdf.ValueTypeNames.Token, \
                Sdf.VariabilityUniform)
        infoIdAttrSpec.default = nodeIdentifier

    schemaLayer.Save()
Esempio n. 21
0
def UpdateSchemaWithSdrNode(schemaLayer, sdrNode):
    """
    Updates the given schemaLayer with primSpec and propertySpecs from sdrNode
    metadata. It consume the following attributes (that manifest as Sdr 
    metadata) in addition to many of the standard Sdr metadata
    specified and parsed (via its parser plugin).

    Node Level Metadata:
        - "schemaName": Name of the new schema populated from the given sdrNode
          (Required)
        - "schemaKind": Specifies the UsdSchemaKind for the schema being
          populated from the sdrNode. (note that this does not support
          multi-applied schema kinds).
        - "schemaBase": Base schema from which the new schema should inherit
          from. Note this defaults to "APISchemaBase" for an api schema or 
          "Typed" for a concrete scheme.
        - "usdSchemaClass": Specified the equivalent schema directly generated
          by USD (sourceType: USD). This is used to make sure duplicate
          properties already specified in the USD schema are not populated in
          the new API schema. Note this is only used when we are dealing with an
          API schema.
        - "apiSchemaAutoApplyTo": The Schemas to which the sdrNode populated 
          (API) schema will autoApply to.
        - "tfTypeNameSuffix": Class name which will get registered with TfType 
          system. This gets appended to the domain name to register with TfType.

    Property Level Metadata:
        - USD_VARIABILITY:  A property level metadata, which specified a 
          specific sdrNodeProperty should its usd variability set to Uniform or 
          Varying.
        - USD_SUPPRESS_PROPERTY: A property level metadata, which determines if the
          property should be suppressed from translation from args to property
          spec.
    """
    # Early exit on invalid parameters
    if not schemaLayer:
        Tf.Warn("No Schema Layer provided")
        return
    if not sdrNode:
        Tf.Warn("No valid sdrNode provided")
        return

    sdrNodeMetadata = sdrNode.GetMetadata()

    if SchemaDefiningKeys.SCHEMA_NAME not in sdrNodeMetadata:
        Tf.Warn("Sdr Node does not define a schema name metadata.")
        return
    schemaName = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_NAME]
    if not Tf.IsValidIdentifier(schemaName):
        Tf.RaiseRuntimeError("schemaName (%s) is an invalid identifier; "
                "Provide a valid USD identifer for schemaName, example (%s) "
                %(schemaName, Tf.MakeValidIdentifier(schemaName)))

    tfTypeNameSuffix = None
    if SchemaDefiningKeys.TF_TYPENAME_SUFFIX in sdrNodeMetadata:
        tfTypeNameSuffix = sdrNodeMetadata[SchemaDefiningKeys.TF_TYPENAME_SUFFIX]
        if not Tf.IsValidIdentifier(tfTypeNameSuffix):
            Tf.RaiseRuntimeError("tfTypeNameSuffix (%s) is an invalid " \
                    "identifier" %(tfTypeNameSuffix))

    if SchemaDefiningKeys.SCHEMA_KIND not in sdrNodeMetadata:
        schemaKind = SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaKind = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_KIND]

    # Note: We are not working on dynamic multiapply schemas right now.
    isAPI = schemaKind == SchemaDefiningMiscConstants.SINGLE_APPLY_SCHEMA
    # Fix schemaName and warn if needed
    if isAPI and \
        not schemaName.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created is "
        "an API schema, fixing schemaName to reflect that")
        schemaName = schemaName + SchemaDefiningMiscConstants.API_STRING

    if isAPI and tfTypeNameSuffix and \
        not tfTypeNameSuffix.endswith(SchemaDefiningMiscConstants.API_STRING):
            Tf.Warn("node metadata implies the generated schema being created "
            "is an API schema, fixing tfTypeNameSuffix to reflect that")
            tfTypeNameSuffix = tfTypeNameSuffix + \
                    SchemaDefiningMiscConstants.API_STRING

    if SchemaDefiningKeys.SCHEMA_BASE not in sdrNodeMetadata:
        Tf.Warn("No schemaBase specified in node metadata, defaulting to "
                "APISchemaBase for API schemas else Typed")
        schemaBase = SchemaDefiningMiscConstants.API_SCHEMA_BASE if isAPI \
                else SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaBase = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_BASE]

    apiSchemaAutoApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO in sdrNodeMetadata:
        apiSchemaAutoApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO] \
                .split('|')

    usdSchemaClass = None
    if isAPI and SchemaDefiningKeys.USD_SCHEMA_CLASS in sdrNodeMetadata:
        usdSchemaClass = \
            sdrNodeMetadata[SchemaDefiningKeys.USD_SCHEMA_CLASS]

    primSpec = schemaLayer.GetPrimAtPath(schemaName)

    if (primSpec):
        # if primSpec already exist, remove entirely and recreate using the 
        # parsed sdr node
        if primSpec.nameParent:
            del primSpec.nameParent.nameChildren[primSpec.name]
        else:
            del primSpec.nameRoot.nameChildren[primSpec.name]

    primSpec = Sdf.PrimSpec(schemaLayer, schemaName, Sdf.SpecifierClass,
            "" if isAPI else schemaName)
    
    primSpec.inheritPathList.explicitItems = ["/" + schemaBase]

    primSpecCustomData = {}
    if isAPI:
        primSpecCustomData["apiSchemaType"] = schemaKind 
    if tfTypeNameSuffix:
        # Defines this classname for TfType system
        # can help avoid duplicate prefix with domain and className
        # Tf type system will automatically pick schemaName as tfTypeName if
        # this is not set!
        primSpecCustomData["className"] = tfTypeNameSuffix

    if apiSchemaAutoApplyTo:
        primSpecCustomData['apiSchemaAutoApplyTo'] = \
            Vt.TokenArray(apiSchemaAutoApplyTo)
    primSpec.customData = primSpecCustomData

    doc = sdrNode.GetHelp()
    if doc != "":
        primSpec.documentation = doc

    # gather properties from node directly generated from USD (sourceType: USD)
    # Use the usdSchemaClass tag when the generated schema being defined is an 
    # API schema
    usdSchemaNode = None
    if usdSchemaClass:
        reg = Sdr.Registry()
        usdSchemaNode = reg.GetNodeByIdentifierAndType(usdSchemaClass, 
                SchemaDefiningMiscConstants.USD_SOURCE_TYPE)

    # Create attrSpecs from input parameters
    for propName in sdrNode.GetInputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetInput(propName), 
                usdSchemaNode)

    # Create attrSpecs from output parameters
    for propName in sdrNode.GetOutputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetOutput(propName), 
                usdSchemaNode, False)

    # Extra attrSpec
    schemaBasePrimDefinition = \
        Usd.SchemaRegistry().FindConcretePrimDefinition(schemaBase)
    if schemaBasePrimDefinition and \
        SchemaDefiningMiscConstants.NodeDefAPI in \
        schemaBasePrimDefinition.GetAppliedAPISchemas():
            infoIdAttrSpec = Sdf.AttributeSpec(primSpec, \
                    UsdShade.Tokens.infoId, Sdf.ValueTypeNames.Token, \
                    Sdf.VariabilityUniform)
            infoIdAttrSpec.default = sdrNode.GetIdentifier()

    schemaLayer.Save()
Esempio n. 22
0
    def test_FlattenPrimDefinition(self):
        # Verifies that the given spec has exactly the field values enumerated
        # in expectedFieldValues
        def _VerifyExpectedFieldValues(spec, expectedFieldValues):
            for (expectedField, expectedValue) in expectedFieldValues.items():
                self.assertEqual(spec.GetInfo(expectedField), expectedValue)
            for field in spec.ListInfoKeys():
                self.assertIn(field, expectedFieldValues)

        # Verifies that there's a prim spec at path in the layer with the
        # given set of prim spec fields and the expected properties (with their
        # own expected fields.
        def _VerifyExpectedPrimData(layer, path, expectedPrimFields,
                                    expectedProperties):
            # Verify the prim spec and its expected fields.
            spec = layer.GetObjectAtPath(path)
            self.assertTrue(spec)
            _VerifyExpectedFieldValues(spec, expectedPrimFields)

            # Verify the prim spec has exactly the expected properties and
            # each property has the expected fields for each expected property.
            self.assertEqual(len(spec.properties), len(expectedProperties))
            for (propName, fieldValues) in expectedProperties.items():
                propSpec = spec.properties[propName]
                self.assertTrue(propSpec)
                _VerifyExpectedFieldValues(propSpec, fieldValues)

        # Create a new layer with a sublayer for authoring.
        layer = Sdf.Layer.CreateAnonymous(".usda")
        sublayer = Sdf.Layer.CreateAnonymous(".usda")
        layer.subLayerPaths.append(sublayer.identifier)

        # Test flattening a prim definition for a concrete schema directly
        # to a new path in the layer with the def specifier. A new prim spec
        # will be created with given specifier (as well as an over for the
        # not yet existent parent path).
        concretePrimDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            "MetadataTest")
        self.assertTrue(
            concretePrimDef.FlattenTo(layer, "/PrimDefs/ConcreteSchema",
                                      Sdf.SpecifierDef))

        # Expected fields and properties from the concrete schema.
        concretePrimDefPrimFields = {
            "apiSchemas": Sdf.TokenListOp.CreateExplicit([]),
            "documentation": concretePrimDef.GetDocumentation(),
            "hidden": True,
            "testCustomMetadata": "garply",
            "specifier": Sdf.SpecifierDef,
            "typeName": "MetadataTest"
        }
        concretePrimDefProperties = {
            "testAttr": {
                "custom": False,
                "default": "foo",
                "typeName": Sdf.ValueTypeNames.String,
                "allowedTokens": ["bar", "baz"],
                "displayGroup": "Display Group",
                "displayName": "Display Name",
                "documentation": "Testing documentation metadata",
                "hidden": True,
                "testCustomMetadata": "garply",
                "variability": Sdf.VariabilityVarying
            },
            "testRel": {
                "custom": False,
                "displayGroup": "Display Group",
                "displayName": "Display Name",
                "documentation": "Testing documentation metadata",
                "hidden": True,
                "testCustomMetadata": "garply",
                "variability": Sdf.VariabilityUniform
            }
        }

        # Verify the new spec exists and has the correct prim fields and
        # property specs.
        _VerifyExpectedPrimData(layer, "/PrimDefs/ConcreteSchema",
                                concretePrimDefPrimFields,
                                concretePrimDefProperties)

        # Test flattening a prim definition for an API schema directly
        # to a new path in the layer with the fallback over specifier. A new
        # overprim spec will be created.
        apiPrimDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition(
            "CollectionAPI")
        self.assertTrue(apiPrimDef.FlattenTo(layer, "/PrimDefs/APISchema"))

        # Expected fields and properties from the CollectionAPI schema. Note
        # that CollectionAPI is a multiple apply schema but the expected
        # properties have no prefix. This is because the API prim definition is
        # for the CollectionAPI itself, not an applied instance of the API
        # schema.
        apiPrimDefPrimFields = {
            "apiSchemas": Sdf.TokenListOp.CreateExplicit([]),
            "documentation": apiPrimDef.GetDocumentation(),
            "specifier": Sdf.SpecifierOver
        }
        apiPrimDefProperties = {
            "expansionRule": {
                "custom":
                False,
                "default":
                "expandPrims",
                "typeName":
                Sdf.ValueTypeNames.Token,
                "allowedTokens":
                ["explicitOnly", "expandPrims", "expandPrimsAndProperties"],
                "documentation":
                apiPrimDef.GetPropertyDocumentation("expansionRule"),
                "variability":
                Sdf.VariabilityUniform
            },
            "includeRoot": {
                "custom": False,
                "default": None,
                "typeName": Sdf.ValueTypeNames.Bool,
                "documentation":
                apiPrimDef.GetPropertyDocumentation("includeRoot"),
                "variability": Sdf.VariabilityUniform
            },
            "includes": {
                "custom": False,
                "documentation":
                apiPrimDef.GetPropertyDocumentation("includes"),
                "variability": Sdf.VariabilityUniform
            },
            "excludes": {
                "custom": False,
                "documentation":
                apiPrimDef.GetPropertyDocumentation("excludes"),
                "variability": Sdf.VariabilityUniform
            }
        }

        # Verify the new spec exists and has the correct prim fields and
        # property specs.
        _VerifyExpectedPrimData(layer, "/PrimDefs/APISchema",
                                apiPrimDefPrimFields, apiPrimDefProperties)

        # Create stage from our to test the overloads of Flatten that take
        # a UsdPrim parent and a child name.
        stage = Usd.Stage.Open(layer)
        parentPrim = stage.GetPrimAtPath("/PrimDefs")
        self.assertTrue(parentPrim)

        # Flatten the concrete prim def to a new prim under the parent using
        # the current edit target (root layer).
        flattenPrim = concretePrimDef.FlattenTo(parentPrim, "FlattenToNewPrim")
        self.assertTrue(flattenPrim)

        # Verify the new spec exists on the root layer and has the correct prim
        # fields and property specs. Note that FlattenTo was called with the
        # default over specifier.
        concretePrimDefPrimFields["specifier"] = Sdf.SpecifierOver
        _VerifyExpectedPrimData(layer, "/PrimDefs/FlattenToNewPrim",
                                concretePrimDefPrimFields,
                                concretePrimDefProperties)

        # Flatten the API prim def to the prim we just created using the
        # sublayer edit target.
        with Usd.EditContext(stage, sublayer):
            flattenPrim = apiPrimDef.FlattenTo(flattenPrim)
            self.assertTrue(flattenPrim)

        # Verify the new spec exists on the sublayer with the API schema fields
        # and properties while the root layer still has the flattened concrete
        # schema spec.
        _VerifyExpectedPrimData(layer, "/PrimDefs/FlattenToNewPrim",
                                concretePrimDefPrimFields,
                                concretePrimDefProperties)
        _VerifyExpectedPrimData(sublayer, "/PrimDefs/FlattenToNewPrim",
                                apiPrimDefPrimFields, apiPrimDefProperties)

        # Flatten the API prim def again to the same prim but now with the
        # root layer edit target.
        flattenPrim = apiPrimDef.FlattenTo(flattenPrim)
        self.assertTrue(flattenPrim)

        # Verify that the root layer specs fields and properties have been
        # fully replaced to match the API schema prim definition.
        _VerifyExpectedPrimData(layer, "/PrimDefs/FlattenToNewPrim",
                                apiPrimDefPrimFields, apiPrimDefProperties)

        # Build the composed prim definition that would be created for a prim
        # of the type "MetadataTest" with a CollectionAPI named "foo" applied.
        newPrimDef = Usd.SchemaRegistry().BuildComposedPrimDefinition(
            "MetadataTest", ["CollectionAPI:foo"])

        # Flatten the composed prim definition to the already existing root
        # layer spec for the parent of all the other prim's we created.
        self.assertTrue(layer.GetPrimAtPath("/PrimDefs"))
        self.assertTrue(
            newPrimDef.FlattenTo(layer, "/PrimDefs", Sdf.SpecifierDef))

        # The prim fields for the composed prim definition will be the same
        # as the concrete prim definition as prim fields don't come from
        # applied API schemas.
        newPrimDefPrimFields = concretePrimDefPrimFields
        # The apiSchemas metadata will always be set to explicit list of applied
        # API schemas.
        newPrimDefPrimFields["apiSchemas"] = \
            Sdf.TokenListOp.CreateExplicit(["CollectionAPI:foo"])
        # The specifier will still be "over" even though we suggested specifier
        # "def" because the prim spec already existed. The suggested specifier
        # only applies to newly created specs.
        newPrimDefPrimFields["specifier"] = Sdf.SpecifierOver

        # The expected properties are the combined set of properties from the
        # concrete schema and the applied schemas.
        newPrimDefProperties = {}
        for (propName, fieldValues) in concretePrimDefProperties.items():
            newPrimDefProperties[propName] = fieldValues
        # In this case all the properties from the applied multiple apply
        # will have the "collection:foo:" prefix as the schema is applied in
        # this prim definition.
        for (propName, fieldValues) in apiPrimDefProperties.items():
            newPrimDefProperties["collection:foo:" + propName] = fieldValues

        # Verify the prim spec matches the prim definition.
        _VerifyExpectedPrimData(layer, "/PrimDefs", newPrimDefPrimFields,
                                newPrimDefProperties)

        # Verify that the existing children of the prim spec as FlattenTo
        # doesn't clear or overwrite fields that can never be schema metadata.
        self.assertTrue(layer.GetPrimAtPath("/PrimDefs/ConcreteSchema"))
        self.assertTrue(layer.GetPrimAtPath("/PrimDefs/APISchema"))
        self.assertTrue(layer.GetPrimAtPath("/PrimDefs/FlattenToNewPrim"))
Esempio n. 23
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'))
Esempio n. 24
0
def UpdateSchemaWithSdrNode(schemaLayer, sdrNode, renderContext="",
        overrideIdentifier=""):
    """
    Updates the given schemaLayer with primSpec and propertySpecs from sdrNode
    metadata. 

    A renderContext can be provided which is used in determining the
    shaderId namespace, which follows the pattern: 
    "<renderContext>:<SdrShaderNodeContext>:shaderId". Note that we are using a
    node's context (SDR_NODE_CONTEXT_TOKENS) here to construct the shaderId
    namespace, so shader parsers should make sure to use appropriate
    SDR_NODE_CONTEXT_TOKENS in the node definitions.

    overrideIdentifier parameter is the identifier which should be used when 
    the identifier of the node being processed differs from the one Sdr will 
    discover at runtime, such as when this function is def a node constructed 
    from an explicit asset path. This should only be used when clients know the 
    identifier being passed is the true identifier which sdr Runtime will 
    provide when querying using GetShaderNodeByIdentifierAndType, etc.

    It consumes the following attributes (that manifest as Sdr 
    metadata) in addition to many of the standard Sdr metadata
    specified and parsed (via its parser plugin).

    Node Level Metadata:
        - "schemaName": Name of the new schema populated from the given sdrNode
          (Required)
        - "schemaKind": Specifies the UsdSchemaKind for the schema being
          populated from the sdrNode. (Note that this does not support
          multiple apply schema kinds).
        - "schemaBase": Base schema from which the new schema should inherit
          from. Note this defaults to "APISchemaBase" for an API schema or 
          "Typed" for a concrete scheme.
        - "apiSchemasForAttrPruning": A list of core API schemas which will be
          composed together and any shared shader property from this prim
          definition is pruned from the resultant schema. 
        - "typedSchemaForAttrPruning": A core typed schema which will be
          composed together with the apiSchemasForAttrPruning and any shared 
          shader property from this prim definition is pruned from the 
          resultant schema. If no typedSchemaForAttrPruning is provided then 
          only the apiSchemasForAttrPruning are composed to create a prim 
          definition. This will only be used when creating an APISchema.
        - "apiSchemaAutoApplyTo": The schemas to which the sdrNode populated 
          API schema will autoApply to.
        - "apiSchemaCanOnlyApplyTo": If specified, the API schema generated 
          from the sdrNode can only be validly applied to this set of schemas.
        - "providesUsdShadeConnectableAPIBehavior": Used to enable a 
          connectability behavior for an API schema.
        - "isUsdShadeContainer": Only used when
          providesUsdShadeConnectableAPIBehavior is set to true. Marks the
          connectable prim as a UsdShade container type.
        - "requiresUsdShadeEncapsulation": Only used when
          providesUsdShadeConnectableAPIBehavior is set to true. Configures the
          UsdShade encapsulation rules governing its connectableBehavior.
        - "tfTypeNameSuffix": Class name which will get registered with TfType 
          system. This gets appended to the domain name to register with TfType.
        - "schemaPropertyNSPrefixOverride": Node level metadata which can drive
          all node's properties namespace prefix. This can be useful for
          non connectable nodes which should not get UsdShade inputs and outputs
          namespace prefix.

    Property Level Metadata:
        - "usdVariability": Property level metadata which specifies a specific 
          sdrNodeProperty should have its USD variability set to Uniform or 
          Varying
        - "usdSuppressProperty": A property level metadata which determines if 
          the property should be suppressed from translation from args to 
          property spec.
        - "propertyNSPrefixOverride": Provides a way to override a property's
          namespace from the default (inputs:/outputs:) or from a node's
          schemaPropertyNSPrefixOverride metadata.

    Sdr Property Metadata to SdfPropertySpec Translations
        - A "null" value for Widget sdrProperty metadata translates to 
          SdfPropertySpec Hidden metadata.
        - SdrProperty's Help metadata (Label metadata if Help metadata not 
          provided) translates to SdfPropertySpec's Documentation string 
          metadata.
        - SdrProperty's Page metadata translates to SdfPropertySpec's
          DisplayGroup metadata.
        - SdrProperty's Label metadata translates to SdfPropertySpec's
          DisplayName metadata.
        - SdrProperty's Options translates to SdfPropertySpec's AllowedTokens.
        - SdrProperty's Default value translates to SdfPropertySpec's Default
          value.
        - Connectable input properties translates to InterfaceOnly
          SdfPropertySpec's CONNECTABILITY.
    """

    import distutils.util
    import os

    # Early exit on invalid parameters
    if not schemaLayer:
        Tf.Warn("No Schema Layer provided")
        return
    if sdrNode is None:
        # This is a workaround to iterate through invalid sdrNodes (nodes not 
        # having any input or output properties). Currently these nodes return
        # false when queried for IsValid().
        # Refer: pxr/usd/ndr/node.h#140-149
        Tf.Warn("No valid sdrNode provided")
        return

    sdrNodeMetadata = sdrNode.GetMetadata()

    if SchemaDefiningKeys.SCHEMA_NAME not in sdrNodeMetadata:
        Tf.Warn("Sdr Node (%s) does not define a schema name metadata." \
                %(sdrNode.GetName()))
        return
    schemaName = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_NAME]
    if not Tf.IsValidIdentifier(schemaName):
        Tf.RaiseRuntimeError("schemaName (%s) is an invalid identifier; "
                "Provide a valid USD identifer for schemaName, example (%s) "
                %(schemaName, Tf.MakeValidIdentifier(schemaName)))

    tfTypeNameSuffix = None
    if SchemaDefiningKeys.TF_TYPENAME_SUFFIX in sdrNodeMetadata:
        tfTypeNameSuffix = sdrNodeMetadata[SchemaDefiningKeys.TF_TYPENAME_SUFFIX]
        if not Tf.IsValidIdentifier(tfTypeNameSuffix):
            Tf.RaiseRuntimeError("tfTypeNameSuffix (%s) is an invalid " \
                    "identifier" %(tfTypeNameSuffix))

    if SchemaDefiningKeys.SCHEMA_KIND not in sdrNodeMetadata:
        schemaKind = SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaKind = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_KIND]

    # Note: We are not working on dynamic multiple apply schemas right now.
    isAPI = schemaKind == SchemaDefiningMiscConstants.SINGLE_APPLY_SCHEMA
    # Fix schemaName and warn if needed
    if isAPI and \
        not schemaName.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created is "
        "an API schema, fixing schemaName to reflect that")
        schemaName = schemaName + SchemaDefiningMiscConstants.API_STRING

    if isAPI and tfTypeNameSuffix and \
        not tfTypeNameSuffix.endswith(SchemaDefiningMiscConstants.API_STRING):
            Tf.Warn("node metadata implies the generated schema being created "
            "is an API schema, fixing tfTypeNameSuffix to reflect that")
            tfTypeNameSuffix = tfTypeNameSuffix + \
                    SchemaDefiningMiscConstants.API_STRING

    if SchemaDefiningKeys.SCHEMA_BASE not in sdrNodeMetadata:
        Tf.Warn("No schemaBase specified in node metadata, defaulting to "
                "APISchemaBase for API schemas else Typed")
        schemaBase = SchemaDefiningMiscConstants.API_SCHEMA_BASE if isAPI \
                else SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaBase = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_BASE]

    apiSchemaAutoApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO in sdrNodeMetadata:
        apiSchemaAutoApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO] \
                .split('|')

    apiSchemaCanOnlyApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_CAN_ONLY_APPLY_TO in sdrNodeMetadata:
        apiSchemaCanOnlyApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_CAN_ONLY_APPLY_TO] \
                .split('|')

    providesUsdShadeConnectableAPIBehavior = False
    if SchemaDefiningKeys.PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR in \
            sdrNodeMetadata:
        providesUsdShadeConnectableAPIBehavior = \
            distutils.util.strtobool(sdrNodeMetadata[SchemaDefiningKeys. \
                PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR])

    apiSchemasForAttrPruning = None
    if SchemaDefiningKeys.API_SCHEMAS_FOR_ATTR_PRUNING in sdrNodeMetadata:
        apiSchemasForAttrPruning = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMAS_FOR_ATTR_PRUNING] \
                .split('|')

    typedSchemaForAttrPruning = ""
    if isAPI and \
            SchemaDefiningKeys.TYPED_SCHEMA_FOR_ATTR_PRUNING in sdrNodeMetadata:
        typedSchemaForAttrPruning = \
            sdrNodeMetadata[SchemaDefiningKeys.TYPED_SCHEMA_FOR_ATTR_PRUNING]

    schemaPropertyNSPrefixOverride = None
    if SchemaDefiningKeys.SCHEMA_PROPERTY_NS_PREFIX_OVERRIDE in sdrNodeMetadata:
        schemaPropertyNSPrefixOverride = \
            sdrNodeMetadata[ \
                SchemaDefiningKeys.SCHEMA_PROPERTY_NS_PREFIX_OVERRIDE]

    usdSchemaReg = Usd.SchemaRegistry()

    # determine if the node being processed provides UsdShade-Connectability, 
    # this helps in determining what namespace to use and also to report error 
    # if a non-connectable node has outputs properties, which is malformed.
    # - Does the node derive from a schemaBase which provides connectable
    # behavior. Warn if schemaPropertyNSPrefixOverride is also specified, as 
    # these metadata won't be used.
    # - If no schemaBase then we default to UsdShade connectable node's 
    # inputs:/outputs: namespace prefix, unless schemaPropertyNSPrefixOverride 
    # is provided. 
    # - We also report an error if schemaPropertyNSPrefixOverride is provided 
    # and an output property is found on the node being processed.
    schemaBaseProvidesConnectability = UsdShade.ConnectableAPI. \
            HasConnectableAPI(usdSchemaReg.GetTypeFromName(schemaBase))

    if (len(sdrNode.GetOutputNames()) > 0 and \
            schemaPropertyNSPrefixOverride is not None and \
            not _IsNSPrefixConnectableAPICompliant( \
                schemaPropertyNSPrefixOverride)):
        Tf.RaiseRuntimeError("Presence of (%s) output parameters contradicts " \
            "the presence of schemaPropertyNSPrefixOverride (\"%s\"), as it " \
            "is illegal for non-connectable nodes to contain output " \
            "parameters, or shader nodes' outputs to not have the \"outputs\"" \
            "namespace prefix." %(len(sdrNode.GetOutputNames()), \
            schemaPropertyNSPrefixOverride))

    if (schemaBaseProvidesConnectability and \
            schemaPropertyNSPrefixOverride is not None and \
            not _IsNSPrefixConnectableAPICompliant( \
                schemaPropertyNSPrefixOverride)):
        Tf.Warn("Node %s provides UsdShade-Connectability as it derives from " \
                "%s, schemaPropertyNSPrefixOverride \"%s\" will not be used." \
                %(schemaName, schemaBase, schemaPropertyNSPrefixOverride))
        # set schemaPropertyNSPrefixOverride to "inputs", assuming default 
        # UsdShade Connectability namespace prefix
        schemaPropertyNSPrefixOverride = "inputs"

    primSpec = schemaLayer.GetPrimAtPath(schemaName)

    if (primSpec):
        # if primSpec already exist, remove entirely and recreate using the 
        # parsed sdr node
        if primSpec.nameParent:
            del primSpec.nameParent.nameChildren[primSpec.name]
        else:
            del primSpec.nameRoot.nameChildren[primSpec.name]

    primSpec = Sdf.PrimSpec(schemaLayer, schemaName, Sdf.SpecifierClass,
            "" if isAPI else schemaName)
    
    primSpec.inheritPathList.explicitItems = ["/" + schemaBase]

    primSpecCustomData = {}
    if isAPI:
        primSpecCustomData["apiSchemaType"] = schemaKind 
    if tfTypeNameSuffix:
        # Defines this classname for TfType system
        # can help avoid duplicate prefix with domain and className
        # Tf type system will automatically pick schemaName as tfTypeName if
        # this is not set!
        primSpecCustomData["className"] = tfTypeNameSuffix

    if apiSchemaAutoApplyTo:
        primSpecCustomData['apiSchemaAutoApplyTo'] = \
            Vt.TokenArray(apiSchemaAutoApplyTo)
    if apiSchemaCanOnlyApplyTo:
        primSpecCustomData['apiSchemaCanOnlyApplyTo'] = \
            Vt.TokenArray(apiSchemaCanOnlyApplyTo)

    if providesUsdShadeConnectableAPIBehavior:
        extraPlugInfo = {
            SchemaDefiningKeys.PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR \
                    : True
        }
        for propKey in [SchemaDefiningKeys.IS_USD_SHADE_CONTAINER, \
                SchemaDefiningKeys.REQUIRES_USD_SHADE_ENCAPSULATION]:
            if propKey in sdrNodeMetadata:
                # Since we want to assign the types for these to bool and
                # because in python boolean type is a subset of int, we need to
                # do following instead of assign the propValue directly.
                propValue = distutils.util.strtobool(sdrNodeMetadata[propKey])
                extraPlugInfo[propKey] = bool(propValue)

        primSpecCustomData['extraPlugInfo'] = extraPlugInfo

    primSpec.customData = primSpecCustomData

    doc = sdrNode.GetHelp()
    if doc != "":
        primSpec.documentation = doc

    # gather properties from a prim definition generated by composing apiSchemas
    # provided by apiSchemasForAttrPruning metadata.
    primDefForAttrPruning = None
    if apiSchemasForAttrPruning:
        primDefForAttrPruning = usdSchemaReg.BuildComposedPrimDefinition(
                typedSchemaForAttrPruning, apiSchemasForAttrPruning)

    # Create attrSpecs from input parameters
    for propName in sdrNode.GetInputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetInput(propName), 
                primDefForAttrPruning, schemaPropertyNSPrefixOverride)

    # Create attrSpecs from output parameters
    # Note that we always want outputs: namespace prefix for output attributes.
    for propName in sdrNode.GetOutputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetOutput(propName), 
                primDefForAttrPruning, UsdShade.Tokens.outputs[:-1], False)

    # Create token shaderId attrSpec -- only for shader nodes
    if (schemaBaseProvidesConnectability or \
            schemaPropertyNSPrefixOverride is None or \
            _IsNSPrefixConnectableAPICompliant(schemaPropertyNSPrefixOverride)):
        shaderIdAttrName = Sdf.Path.JoinIdentifier( \
                [renderContext, sdrNode.GetContext(), 
                    PropertyDefiningKeys.SHADER_ID])
        shaderIdAttrSpec = Sdf.AttributeSpec(primSpec, shaderIdAttrName,
                Sdf.ValueTypeNames.Token, Sdf.VariabilityUniform)

        # Since users shouldn't need to be aware of shaderId attribute, we put 
        # this in "Internal" displayGroup.
        shaderIdAttrSpec.displayGroup = \
                PropertyDefiningKeys.INTERNAL_DISPLAY_GROUP

        # Use the identifier if explicitly provided, (it could be a shader node
        # queried using an explicit path), else use sdrNode's registered 
        # identifier.
        nodeIdentifier = overrideIdentifier if overrideIdentifier else \
                sdrNode.GetIdentifier()
        shaderIdAttrSpec.default = nodeIdentifier

    # Extra attrSpec
    schemaBasePrimDefinition = \
        Usd.SchemaRegistry().FindConcretePrimDefinition(schemaBase)
    if schemaBasePrimDefinition and \
        SchemaDefiningMiscConstants.NodeDefAPI in \
        schemaBasePrimDefinition.GetAppliedAPISchemas():
            infoIdAttrSpec = Sdf.AttributeSpec(primSpec, \
                    UsdShade.Tokens.infoId, Sdf.ValueTypeNames.Token, \
                    Sdf.VariabilityUniform)
            infoIdAttrSpec.default = nodeIdentifier

    schemaLayer.Save()
Esempio n. 25
0
    def test_WritingSchemaFallbacks(self):
        # Test the writing of fallback types defined in the schema through the
        # stage API.

        # Our test schema plugin has some fallbacks defined. Verify that we
        # can get these as dictionary from the schema registry
        schemaFallbacks = {
            "ValidType_1" : Vt.TokenArray(["FallbackType_1"]),
            "ValidType_2" : Vt.TokenArray(["FallbackType_2", "FallbackType_1"])
        }
        self.assertEqual(Usd.SchemaRegistry().GetFallbackPrimTypes(),
                         schemaFallbacks)

        # Create a new empty layer and stage from that layer. There will be
        # no fallbackPrimTypes set on the newly opened stage
        layer = Sdf.Layer.CreateNew("tempNew.usda")
        self.assertTrue(layer)
        stage = Usd.Stage.Open(layer)
        self.assertTrue(stage)
        self.assertFalse(stage.GetMetadata("fallbackPrimTypes"))
        self.assertFalse(layer.GetPrimAtPath('/').GetInfo('fallbackPrimTypes'))

        # Create a prim spec on the layer and save the layer itself. There will
        # be no fallback metadata on the stage since we saved through the
        # layer's API.
        spec = Sdf.PrimSpec(layer, "ValidPrim", Sdf.SpecifierDef, "ValidType_2")
        self.assertTrue(stage.GetPrimAtPath("/ValidPrim"))
        layer.Save()
        self.assertFalse(stage.GetMetadata("fallbackPrimTypes"))
        self.assertFalse(layer.GetPrimAtPath('/').GetInfo('fallbackPrimTypes'))

        # Now write the schema fallbacks to the layer using the stage API. This 
        # will write the schema fallbacks dictionary to the root layer. Verify 
        # that this layer change does not a cause a full stage resync.
        with ChangeNoticeVerifier(self, expectedResyncAll=False):
            stage.WriteFallbackPrimTypes()
        self.assertEqual(stage.GetMetadata("fallbackPrimTypes"), 
                         schemaFallbacks)
        self.assertEqual(layer.GetPrimAtPath('/').GetInfo('fallbackPrimTypes'),
                         schemaFallbacks)

        # Now manually author a different dictionary of fallback to the root
        # layer. This will trigger a full stage resync and changes the stage's
        # fallback types.
        newFallbacks = {
            "ValidType_1" : Vt.TokenArray(["ValidType_2, FallbackType_2"]),
            "InValidType_1" : Vt.TokenArray(["ValidType_1"])
        }
        with ChangeNoticeVerifier(self, expectedResyncAll=True):
            layer.GetPrimAtPath('/').SetInfo('fallbackPrimTypes', 
                                             newFallbacks)
        self.assertEqual(stage.GetMetadata("fallbackPrimTypes"), 
                         newFallbacks)
        self.assertEqual(layer.GetPrimAtPath('/').GetInfo('fallbackPrimTypes'),
                         newFallbacks)

        # Write the schema fallbacks again and verify that it will add fallback 
        # types to the metadata dictionary from the schema registry but only for
        # types that aren't already in the dictionary.
        with ChangeNoticeVerifier(self, expectedResyncAll=False):
            stage.WriteFallbackPrimTypes()
        postSaveFallbacks = {
            "ValidType_1" : Vt.TokenArray(["ValidType_2, FallbackType_2"]),
            "ValidType_2" : Vt.TokenArray(["FallbackType_2", "FallbackType_1"]),
            "InValidType_1" : Vt.TokenArray(["ValidType_1"])
        }
        self.assertEqual(stage.GetMetadata("fallbackPrimTypes"), 
                         postSaveFallbacks)
        self.assertEqual(layer.GetPrimAtPath('/').GetInfo('fallbackPrimTypes'),
                         postSaveFallbacks)
Esempio n. 26
0
    def test_TypedSchemaWithFallbackAPISchemas(self):
        """
        Tests the prim definition for schema prim type that has API schemas
        applied to it in its generated schema.
        """

        # Find the prim definition for the test single apply schema. It has
        # some properties defined.
        singleApplyAPIDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition(
            "TestSingleApplyAPI")
        self.assertTrue(singleApplyAPIDef)
        self.assertEqual(
            singleApplyAPIDef.GetPropertyNames(),
            ["single:bool_attr", "single:token_attr", "single:relationship"])
        self.assertEqual(singleApplyAPIDef.GetDocumentation(),
                         "Test single apply API schema")

        # Find the prim definition for the test multi apply schema. It has
        # some properties defined. Note that the properties in the multi apply
        # definition are not prefixed yet.
        multiApplyAPIDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition(
            "TestMultiApplyAPI")
        self.assertTrue(multiApplyAPIDef)
        self.assertEqual(multiApplyAPIDef.GetPropertyNames(),
                         ["bool_attr", "token_attr", "relationship"])
        self.assertEqual(multiApplyAPIDef.GetDocumentation(),
                         "Test multi-apply API schema")

        # Find the prim definition for the concrete prim type with fallback
        # API schemas. You can query its API schemas and it will have properties
        # from those schemas already.
        primDef = Usd.SchemaRegistry().FindConcretePrimDefinition(
            "TestWithFallbackAppliedSchema")
        self.assertTrue(primDef)
        self.assertEqual(primDef.GetAppliedAPISchemas(),
                         ["TestMultiApplyAPI:fallback", "TestSingleApplyAPI"])
        self.assertEqual(sorted(primDef.GetPropertyNames()), [
            "multi:fallback:bool_attr", "multi:fallback:relationship",
            "multi:fallback:token_attr", "single:bool_attr",
            "single:relationship", "single:token_attr", "testAttr", "testRel"
        ])
        # Note that prim def documentation does not come from the fallback API
        # schemas.
        self.assertEqual(primDef.GetDocumentation(),
                         "Test with fallback API schemas")

        # Verify property specs for all named properties.
        for propName in primDef.GetPropertyNames():
            self.assertTrue(primDef.GetSchemaPropertySpec(propName))

        # Verify fallback value and type for properties defined in the
        # concrete prim
        testAttr = primDef.GetSchemaAttributeSpec("testAttr")
        self.assertEqual(testAttr.default, "foo")
        self.assertEqual(testAttr.typeName.cppTypeName, "std::string")

        self.assertTrue(primDef.GetSchemaRelationshipSpec("testRel"))

        # Verify fallback value and type for properties from the single applied
        # schema. These properties will return the same property spec as the
        # API schema prim definition.
        singleBoolAttr = primDef.GetSchemaAttributeSpec("single:bool_attr")
        self.assertEqual(
            singleBoolAttr,
            singleApplyAPIDef.GetSchemaAttributeSpec("single:bool_attr"))
        self.assertEqual(singleBoolAttr.default, True)
        self.assertEqual(singleBoolAttr.typeName.cppTypeName, "bool")

        singleTokenAttr = primDef.GetSchemaAttributeSpec("single:token_attr")
        self.assertEqual(
            singleTokenAttr,
            singleApplyAPIDef.GetSchemaAttributeSpec("single:token_attr"))
        self.assertEqual(singleTokenAttr.default, "bar")
        self.assertEqual(singleTokenAttr.typeName.cppTypeName, "TfToken")

        singleRelationship = primDef.GetSchemaRelationshipSpec(
            "single:relationship")
        self.assertTrue(singleRelationship)
        self.assertEqual(
            singleRelationship,
            singleApplyAPIDef.GetSchemaRelationshipSpec("single:relationship"))

        # Verify fallback value and type for properties from the multi applied
        # schema. These properties will return the same property spec as the
        # API schema prim definition even the properties on the concrete prim
        # definion are namespace prefixed.
        multiTokenAttr = primDef.GetSchemaAttributeSpec(
            "multi:fallback:token_attr")
        self.assertEqual(multiTokenAttr,
                         multiApplyAPIDef.GetSchemaAttributeSpec("token_attr"))
        self.assertEqual(multiTokenAttr.default, "foo")
        self.assertEqual(multiTokenAttr.typeName.cppTypeName, "TfToken")

        multiRelationship = primDef.GetSchemaRelationshipSpec(
            "multi:fallback:relationship")
        self.assertTrue(multiRelationship)
        self.assertEqual(
            multiRelationship,
            multiApplyAPIDef.GetSchemaRelationshipSpec("relationship"))

        # Verify the case where the concrete type overrides a property from
        # one of its applied API schemas. In this case the property spec from
        # the concrete prim is returned instead of the property spec from the
        # API schema.
        multiBoolAttr = primDef.GetSchemaAttributeSpec(
            "multi:fallback:bool_attr")
        apiBoolAttr = multiApplyAPIDef.GetSchemaAttributeSpec("bool_attr")
        self.assertNotEqual(multiBoolAttr, apiBoolAttr)
        self.assertEqual(multiBoolAttr.default, False)
        self.assertEqual(apiBoolAttr.default, True)
        self.assertEqual(multiBoolAttr.typeName.cppTypeName, "bool")
        self.assertEqual(apiBoolAttr.typeName.cppTypeName, "bool")
Esempio n. 27
0
    def createAppliedSchemasSection(self):
        # USD version 0.21.2 is required because of
        # Usd.SchemaRegistry().GetPropertyNamespacePrefix()
        if Usd.GetVersion() < (0, 21, 2):
            return

        showAppliedSchemasSection = False

        # loop on all applied schemas and store all those
        # schema into a dictionary with the attributes.
        # Storing the schema into a dictionary allow us to
        # group all instances of a MultipleApply schema together
        # so we can later display them into the same UI section.
        #
        # By example, if UsdCollectionAPI is applied twice, UsdPrim.GetAppliedSchemas()
        # will return ["CollectionAPI:instance1","CollectionAPI:instance2"] but we want to group
        # both instance inside a "CollectionAPI" section.
        #
        schemaAttrsDict = {}
        appliedSchemas = self.prim.GetAppliedSchemas()
        for schema in appliedSchemas:
            if Usd.GetVersion() > (0, 21, 5):
                typeAndInstance = Usd.SchemaRegistry().GetTypeNameAndInstance(
                    schema)
            else:
                typeAndInstance = Usd.SchemaRegistry().GetTypeAndInstance(
                    schema)
            typeName = typeAndInstance[0]
            schemaType = Usd.SchemaRegistry().GetTypeFromName(typeName)

            if schemaType.pythonClass:
                isMultipleApplyAPISchema = Usd.SchemaRegistry(
                ).IsMultipleApplyAPISchema(typeName)
                if isMultipleApplyAPISchema:
                    # get the attributes names. They will not include the namespace and instance name.
                    instanceName = typeAndInstance[1]
                    attrList = schemaType.pythonClass.GetSchemaAttributeNames(
                        False, instanceName)
                    # build the real attr name
                    # By example, collection:lightLink:includeRoot
                    namespace = Usd.SchemaRegistry(
                    ).GetPropertyNamespacePrefix(typeName)
                    prefix = namespace + ":" + instanceName + ":"
                    attrList = [prefix + i for i in attrList]

                    if typeName in schemaAttrsDict:
                        schemaAttrsDict[typeName] += attrList
                    else:
                        schemaAttrsDict[typeName] = attrList
                else:
                    attrList = schemaType.pythonClass.GetSchemaAttributeNames(
                        False)
                    schemaAttrsDict[typeName] = attrList

                # The "Applied Schemas" will be only visible if at least
                # one applied Schemas has attribute.
                if not showAppliedSchemasSection:
                    for attr in attrList:
                        if self.attrS.hasAttribute(attr):
                            showAppliedSchemasSection = True
                            break

        # Create the "Applied Schemas" section
        # with all the applied schemas
        if showAppliedSchemasSection:
            with ufeAeTemplate.Layout(self, 'Applied Schemas', collapse=True):
                for typeName, attrs in schemaAttrsDict.items():
                    typeName = self.sectionNameFromSchema(typeName)
                    self.createSection(typeName, attrs, False)