A standard UsdAttribute.Get() presumably returns the evaluated expression, but what is the API to get the raw expression?
We currently do not have any USD API to get to the raw expression. There are a couple different ideas for exposing this:
- Add a new field to the SdfAssetPath object
- Add a separate function on UsdAttribute like GetRawAssetPath (name TBD) that would only be applicable for asset path-valued attributes.
- Add an optional separate parameter to UsdAttribute::Get for controlling what gets put in the resulting SdfAssetPath object.
We haven’t come to any conclusions here though, so any feedback would certainly be welcome!
So again, I’m wondering how I can get at this “active” dictionary of values for a given prim?
Like you said, the “active” variables that apply depend on what site in the composed prim the expression that uses those variables is authored: e.g., is it authored just in the root layer of the stage – in which case the variables in the root and session layers would apply – or is it authored across some series of references, each of which may introduce other variables.
For an attribute, you should be able to get the the applicable dictionary of values via its UsdResolveInfo. Something like:
UsdAttribute attr = stage->GetAttributeAtPath(...);
UsdResolveInfo resolveInfo = attr.GetResolveInfo();
const VtDictionary expressionVars = resolveInfo.GetNode().GetLayerStack()->GetExpressionVariables();
We could definitely consider adding this as first-class API on UsdAttribute itself if that’s useful.
When flattening a layer stack I expect the source layer opinions to be preserved to the greatest extent possible… Stage variable expressions in variant opinions survive this function, FWIW. But expressions in reference and payload arcs do not
During flattening, we have to anchor any authored asset paths to the layer they were originally authored in to ensure that they resolve to the same location when they’re written to the flattened layer. For example, if you have /test/root.usda
with a sublayer ./foo/bar/sub.usda
, and in the sublayer you have a prim that references ./ref.usda
, flattening has to anchor and write out /test/foo/bar/ref.usda
for that reference. That way, the client is guaranteed that that reference will resolve to the same layer it did originally, no matter where you write the flattened layer out. And if that reference is specified using an expression, that expression has to be evaluated t do the anchoring.
I wonder if one thing we could do here though is to add an anchor
function to the expression language. So for example, if you had:
asset a = @`"./foo/${VAR}/baz.png"`@
flattening could detect that a
is an expression and author:
asset a = @`anchor(<source layer path>, "./foo/${VAR}/baz.png")`@
That would keep the original expression but still ensure that evaluating and resolving it later on would give you the same result as before.