Question regarding AllowedTokens

Hi,

Is there a significant difference between getting the allowedTokens meta data through UsdPrimDefinition vs directly from the attribute itself? If there is, when should I choose one over the other?

PXR_NS::VtTokenArray allowedTokens;
const PXR_NS::UsdPrimDefinition& primDef = prim.GetPrimDefinition();
primDef.GetPropertyMetadata(attr->GetName(),PXR_NS::SdfFieldKeys->AllowedTokens,&allowedTokens)

VS

 PXR_NS::VtTokenArray allowedTokens;
 attr.GetMetadata(PXR_NS::SdfFieldKeys->AllowedTokens,&allowedTokens)

AllowedTokens on schema properties ideally would not be over rideable in scenes, since they are tied to coded schema behavior. So I’d recommend going to the PrimDefinition.

2 Likes

To be more clear, we do have some properties that are tied to our custom schema.

e.g

#usda 1.0

def Xform "root"
{
    def Xform "dummy"
    {
        token foo:flags:preset = "Default" (
            allowedTokens = ["Default", "A", "B", "C", "D"]
        )
    }
}

In my original approach ( code below ) I was only asking PrimDefinition to give me allowedTokens but in the case of above example, GetPropertyMetadata returns false.

PXR_NS::VtTokenArray allowedTokens;
const PXR_NS::UsdPrimDefinition& primDef = attrWrapper->usdPrim().GetPrimDefinition();

// returns true if a fallback value is defined for the given metadata
if (primDef.GetPropertyMetadata(attrWrapper->name(),PXR_NS::SdfFieldKeys->AllowedTokens,&allowedTokens)) {
    // create an Enum Attribute from a list of allowed tokens
} else {
    // create an Enum Attribute from the current value only
}

I think if I understand this correctly, I should first ask PrimDefinition and if that fails, then ask the metadata on the attribute to retrieve the allowedTokens. something like this:

    PXR_NS::VtTokenArray allowedTokens;
    const PXR_NS::UsdPrimDefinition& primDef = attrWrapper->usdPrim().GetPrimDefinition();
    if (primDef.GetPropertyMetadata(attrWrapper->name(),PXR_NS::SdfFieldKeys->AllowedTokens,&allowedTokens)) {
        // create an Enum Attribute from a list of allowed tokens
    } else if (attrWrapper->usdAttribute().GetMetadata(PXR_NS::SdfFieldKeys->AllowedTokens, &allowedTokens)) {
        // create an Enum Attribute from a list of allowed tokens tied to certain schema
    }
    else {
        // create an Enum Attribute from current value if both cases above fails
    }

SchemRegistry Prim/Property definitions will only contain metadata fallbacks that were defined as part of the schema in the schema.usda source file - not anything authored in a particular scene.

Querying the UsdProperty directly will always consult both sources - you just won’t be able to tell which one it came from unless you consult the UsdPropertyStack for the property, or additionionally using your first batch of code.