Hey,
A question as to expected behaviour and whether we’re missing any API calls which are expected to be available for SdrProperties?
The issue is when trying to get the new uiHints from an SdrShaderProperty. Following the proposal: UI Hints in USD by agb63 · Pull Request #85 · PixarAnimationStudios/OpenUSD-proposals
PXR_NS::SdrShaderNodeConstPtr node = PXR_NS::SdrRegistry::GetInstance().GetShaderNodeByIdentifier(PXR_NS::TfToken("TestShaderWithNestedMetadata"));
if(node == nullptr) {
std::cout << "Failed to find shader node 'TestShaderWithNestedMetadata' in registry." << std::endl;
return metadata;
}
PXR_NS::SdrShaderPropertyConstPtr prop = node->GetShaderInput(PXR_NS::TfToken("colorIntensity"));
PXR_NS::VtDictionary vtMetadata;
for (const auto& [key, val] : prop->GetMetadataObject().GetItems()) {
std::cout << "Metadata item: " << key << " : " << val.GetTypeName() << std::endl;
vtMetadata[key] = val;
}
return fromVtDictionary(vtMetadata);
The result we get is:
Metadata item: connectable : bool
Metadata item: help : string
Metadata item: limits : string
Metadata item: sdrUsdDefinitionType : TfToken
Metadata item: uiHints : string
Metadata item: widget : TfToken
The issue is uiHints being a string, whereas we expect it should be a VtDictionary… We can’t necessarily see a way to get that as the nested VtDictionary it was defined as. If we print out the string it is:
"{'displayName': Intensity, 'hidden': 0}"
This makes it much harder to parse, and we believe possibly inconsistent, and we’re hesitant to implement parsing for this if this is not expected.
It’s also worth noting that this would not parse via Python dictionary (given Intensity is undefined, and has no quotes.)
Given there also isn’t any current shaders (which we could find) which utilise the new uiHints format, we had to make our own:
#usda 1.0
def Shader "TestShaderWithNestedMetadata" (
sdrMetadata = {
token role = "TestShaderWithNestedMetadata"
}
)
{
uniform token info:id = "TestShaderWithNestedMetadata"
uniform token info:implementationSource = "sourceAsset"
uniform asset info:glslfx:sourceAsset = @test.glslfx@
float inputs:colorIntensity = 1.0 (
sdrMetadata = {
token help = "Controls the intensity of the output color"
dictionary uiHints = {
token displayName = "Intensity"
bool hidden = 0
}
dictionary limits = {
float min = 0.0
float max = 100.0
}
}
)
color3f outputs:result
}
from pxr import Sdr, Sdf, Usd, UsdShade
# will need to define testDir.
shaderLayerPath = os.path.join(testDir, "testShaderWithNestedMetadata.usda")
stage = Usd.Stage.Open(shaderLayerPath)
assert bool(stage), "Failed to open shader definition stage"
shaderDef = UsdShade.Shader.Get(stage, Sdf.Path("/TestShaderWithNestedMetadata"))
assert bool(shaderDef), "Shader definition prim not found"
discoveryResults = UsdShade.ShaderDefUtils.GetDiscoveryResults(
shaderDef, stage.GetRootLayer().realPath
)
assert len(discoveryResults) > 0, "No discovery results for shader definition"
sdrRegistry = Sdr.Registry()
for discoveryResult in discoveryResults:
sdrRegistry.AddDiscoveryResult(discoveryResult)
(We used an almost empty glslfx file)
-- glslfx version 0.1
-- configuration
{"techniques": {"default": {}}}
-- This file is intentionally empty for testing purposes.
Is this an issue with how we’re registering a custom shader in order to test this functionality, or something I should raise as a bug to the OpenUSD Repo?
Cheers,
James