`specifier` and `typeName` are settable variant fields but are not serializable to USDA
The set of variant fields is defined as being identical to the set of prim fields.
https://github.com/PixarAnimationStudios/OpenUSD/blob/833d130b2d1e607b24822a6b0e59d7baaeb88c53/pxr/usd/sdf/schema.cpp#L995-L996
This means that both specifier and typeName are both supported fields for variants. In fact, because specifier is a required field for prims, it becomes a required field for variants and by default has a value of over.
>>> from pxr import Sdf
>>> l = Sdf.Layer.CreateAnonymous()
>>> v = Sdf.CreateVariantInLayer(l, "/hello", "world", "earth")
>>> v.ListInfoKeys()
['specifier']
>>> v.GetInfo("specifier")
Sdf.SpecifierOver
If you try to author either of these fields, neither serialize to usda and their value is lost.
>>> v.GetMetaDataInfoKeys()
['inactiveIds', 'clipSets', 'payloadAssetDependencies', 'symmetryArguments', 'active', 'uiHints', 'symmetricPeer', 'kind', 'apiSchemas', 'payload', 'typeName', 'suffix', 'customData', 'symmetryFunction', 'sdrMetadata', 'clips', 'permission', 'suffixSubstitutions', 'displayGroupOrder', 'instanceable', 'documentation', 'prefix', 'hidden', 'assetInfo', 'prefixSubstitutions', 'displayName']
>>> v.SetInfo("typeName", "Mesh")
>>> v.GetInfo("typeName")
'Mesh'
>>> l.ExportToString()
>>> print(l.ExportToString())
#usda 1.0
over "hello" (
prepend variantSets = "world"
)
{
variantSet "world" = {
"earth" {
}
}
}
Should the text file format serialize either (or both) of these fields or should schema.cpp remove them from the set of authorable variant fields?
@nvmkuruc to file a corresponding Issue in Core Spec to disambiguate-- Core Spec WG will also add a release note describing the current OpenUSD behavior that would need to be tightened up on a future release.
@nvmkuruc , we think both specifier and typeName should be preserved through serialization and parsing... and believe that crate should already be preserving them. After a bit of back and forth, we agree that a variant spec in usda should be able to contain:
- Just the variant name (
"earth", as today), or - A specifier plus variant name (
def "earth") - there is no real value in specifying "over" if you are not also specifying a typeName, but parser should not care... or - A specifier plus typeName plus variant name (
over Sphere "earth")
This would necessitate a usda file-format version bump in a new asset, but only if the writer detects a variantSpec with either a non-over specifier or a non-empty typeName. Which should also preserve round-tripping of existing usda files.
Regarding the Spec:
- Just calling attention to the special value resolution behavior for
specifier: a defining specifier on a variantSpec will win over anoveron the parent primSpec (this behavior should already be happening) - We're happy to consider a PR for these changes at any time, or we can discuss urgency for us to take it on. Given that we believe there should be no changes necessary outside of the usda file-format code, I'm personally unsure how the Spec wants to discuss the issue... a known oversight/bug in that single file format? In actuality, it's more like we didn't actually plan, originally in Presto, to allow this, but now believe it's a reasonable and good thing.
Hi @spiffmon. Thanks for the information.
The proposed grammar places the variant name after typeName and specifier which resembles a prim spec.
variantSet "world" = {
def Sphere "earth" {}
}
We wanted to see if you'd consider an alternative grammar.
variantSet "world" = {
"earth" : def Sphere {}
"mars" : class {}
"jupiter" : over Sphere {}
"saturn" {}
}
The variant name would precede the specifier and typeName to avoid confusion and be separated by a : if specifier and typeName (or just specifier) are authored.
Following up: We understand the concern that making the variant decls look more like prim defs could be more confusing. However, we're also not keen on introducing a new use of colon, here. Our counter-proposal is, for this likely edge-case that hasn't come up in 20 years of Pixar use of the syntax, to leverage the existing, "generic" metadata syntax. So...
variantSet "world" = {
"earth" (typeName = "Sphere", specifier = "def") {}
}
In today's parser, typeName will already be recognized and processed, though it will not be written back out. specifier will need to gain both reading and writing ability for variants... treating values as quoted strings is just an idea - does it make more sense to treat def, class (and over?) as keywords, here?
I'd vote for keywords. @erslavin any opinions here?
(To clarify, just keywords for specifier, quoted typeName makes sense to me since it's a token.)
Keywords seem better in the sense that it would be a syntax error if anything other than the actual specifier values were used instead of a syntax accept plus semantic check.