完全指南:displayGroup 分组与 shownIf 条件显隐)
OpenUSD 属性级 UI 提示PropertyHints完全指南displayGroup 分组与 shownIf 条件显隐【免费下载链接】OpenUSDUniversal Scene Description项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSDPropertyHints属性级 UI 提示是 OpenUSD 的 UsdUI 域中专门用于描述属性attribute 与 relationship在 DCC 工具或应用 UI 中如何呈现的元数据机制核心解决两个问题属性归入哪个显示分组displayGroup以及基于表达式条件控制属性是否显示shownIf。阅读完本文你将掌握在.usda中编写 PropertyHints、通过UsdUI.PropertyHintsAPI 读写这些提示、利用:分隔符构建嵌套显示组以及用SdfBooleanExpression布尔表达式实现属性动态显隐的完整实战方案。PropertyHints 是什么PropertyHints 是 OpenUSD 中描述属性property级 UI 呈现方式的一组类 schemaschema-likeAPI 与元数据约定。在 PropertyHints.md 中它的定位被明确为为在 UI 中呈现的属性提供 UI 提示覆盖属性所属的显示分组display group如果有以及条件控制属性是否显示在 UI 中的表达式。PropertyHints 属于 UsdUI 的 UI Hints 体系中的属性层级。完整的 UI Hints 分组包括见 overview.mdObjectHints适用于任意 prim 或属性的通用提示如显示名displayName、是否隐藏hiddenPrimHintsprim 级提示如显示组的展开/折叠状态与显示条件PropertyHints属性级提示如属性所属的显示分组、属性的显示条件AttributeHints仅属性attribute级提示如属性值标签及标签的显示顺序。文档特别指出没有专属于 relationship 的 RelationshipHints 分组因为没有任何提示是 relationship 独有的——relationship 使用与 attribute 相同的 PropertyHints测试 testUsdUIHints.py 中的test_RelationshipHintsFromAsset正是用UsdUI.PropertyHints(rel)读取 relationship 的displayGroup与shownIf。在 UsdUI 的 schema 设计上UI Hints 并非schema.usda中正式定义的 schema 类而是直接以名为uiHints的**字典类型元数据metadata dictionary**落在 prim / property 之上。因此 PropertyHints.md 开头就注明该文件不是从schema.usda生成的。UsdUIPropertyHints也明确标注为 schema-like wrapper——它解释UsdProperty上的uiHints字典字段并提供便捷 API但并不继承UsdSchemaBase见 propertyHints.h。UI hints 只是对 UI 呈现方式的建议suggestions最终呈现方式由实现 UI 的工具或应用决定见 [overview.md](https://link.gitcode.com/i/032e85633f96fdb72a221715c36f4721#L162-L166)。一个完整的 PropertyHints 示例原文档给出的基础示例如下一个 prim 上的多个属性各自指定了显示分组其中同时演示了 attribute 与 relationship 两种 property 的写法def PrimWithPropertyHints ( uiHints { string displayName Example prim bool hidden 0 } ) { int exampleAttribute 1 ( uiHints { string displayName An example attribute bool hidden 0 string displayGroup Display Group 1 string shownIf showProperties 1 } ) rel exampleRelationship ( uiHints { string displayName An example relationship bool hidden 0 string displayGroup string shownIf showProperties 1 } ) bool showProperties true }要点拆解displayName与hidden属于 ObjectHints对所有对象通用详见 ObjectHints.mddisplayGroup与shownIf是本篇主角 PropertyHintsrelationship 与 attribute 使用完全一致的uiHints字典结构注意showProperties是属性shownIf表达式引用的变量其解析值是整个表达式的求值输入见下文布尔表达式求值。PropertyHints 字段详解displayGroup显示分组USD 类型stringdisplayGroup指定属性所属的显示分组名称。一个属性只能属于一个显示分组。显示分组是可选的但把相关属性聚拢到同一分组能显著提升 UI 中的查找效率。嵌套分组通过在分组名中使用:分隔符声明嵌套显示组。例如displayGroup设为GroupA:NestedGroup的属性属于 NestedGroup 显示组而 NestedGroup 是 GroupA 的子组。这一语法与 PrimHints 的displayGroupsExpanded/displayGroupsShownIf完全一致可对照 PrimHints.md 中的示例如Body settings:Branch settings以及测试资产 hints.usda 中的displayGroup a group:a nested group来加深理解。空字符串的特殊含义displayGroup 表示属性不归入任何显示组直接落在分组之外的顶层属性列表中。底层实现从 propertyHints.cpp 可以看到GetDisplayGroup()首先通过GetMetadataByDictKey(UsdUIHintKeys-UIHints, UsdUIHintKeys-DisplayGroup, group)读取uiHints.displayGroup若字典中没有该键则回退fallback到已弃用的UsdProperty::GetDisplayGroup()旧式字段。这一回退行为是临时的将在未来版本移除。SetDisplayGroup()则始终写入uiHints字典不再调用已弃用的UsdObject::SetDisplayGroup()只有当环境变量USDUI_WRITE_LEGACY_UI_HINTS开启时才会同步写入旧字段见 propertyHints.cpp 与 objectHints.h。shownIf显示条件表达式USD 类型stringshownIf是一个字符串形式的布尔表达式用于控制属性是否显示在 UI 中表达式求值为true时显示否则在 UI 中省略。该表达式基于 SdfBooleanExpression 实现通常用来测试包含该属性的 prim 上某个已解析属性attribute的值。与hidden的协作shownIf与对象级object-level的hidden提示同时参与属性可见性判定。即只要shownIf求值为false或者hidden为true属性就不可见见 overview.md 与 ObjectHints.md。底层实现GetShownIf()/SetShownIf()同样围绕uiHints字典中的shownIf键读写见 propertyHints.cpp。与displayGroup不同shownIf没有旧式字段可回退未授权时返回空字符串。使用 API 读写 PropertyHints虽然uiHints是普通元数据字典可以直接读写但官方推荐始终使用 API原因有二API 在提示未授权时提供合理的回退值且封装了键路径与类型检查。Python APIfrom pxr import Usd, UsdUI stage Usd.Stage.CreateInMemory() prim stage.DefinePrim(/MyPrim) attr prim.CreateAttribute(myProperty, Sdf.ValueTypeNames.Int) # 获取属性级 UI 提示 hints UsdUI.PropertyHints(attr) # 读取未授权时返回回退值空字符串 print(hints.GetDisplayGroup()) # print(hints.GetShownIf()) # # 写入 hints.SetDisplayGroup(Custom Properties) hints.SetShownIf(myFlag 1) # 再次读取 print(hints.GetDisplayGroup()) # Custom PropertiesUsdUI.PropertyHints接受任意UsdPropertyattribute 或 relationship 均可。Python 绑定见 wrapPropertyHints.cpp其构造器签名为PropertyHints(prop)并暴露GetProperty、GetDisplayGroup、SetDisplayGroup、GetShownIf、SetShownIf六个方法。C API#include pxr/usd/usdUI/propertyHints.h #include pxr/usd/usd/property.h UsdProperty prop ...; // 例如 prim.GetProperty(TfToken(myProperty)) UsdUIPropertyHints hints(prop); std::string group hints.GetDisplayGroup(); // 未授权时回退到旧式字段或空串 std::string shownIf hints.GetShownIf(); hints.SetDisplayGroup(Custom Properties); // 始终写入 uiHints 字典 hints.SetShownIf(myFlag 1);回退值Fallback行为在 testUsdUIHints.py 的test_Fallbacks中验证了对未授权任何提示的属性/HintlessPrim.hintlessAttribute调用PropertyHintsGetDisplayGroup()返回、GetShownIf()返回对默认构造的UsdUI.PropertyHints()无效对象get 操作同样返回回退值而 set 操作会抛出RuntimeError见test_InvalidHintstestUsdUIHints.py。与直接读元数据相比的差异见 overview.mdAPI 返回空字符串作为回退而prim.GetMetadata(uiHints).get(displayName)在未授权时返回None。此外若需要访问自定义的非标准hint 键才建议直接操作uiHints元数据。用:构建嵌套显示组显示组可以无限嵌套。实际 DCC 场景中常把一组相关属性组织成树状结构。以下是与 PrimHints.md 及测试资产相呼应的完整示例——hints.usda 展示了属性与 relationship 混用嵌套分组的真实写法#usda 1.0 def HintsPrim ( uiHints { dictionary displayGroupsExpanded { bool a group 1 bool a group:a nested group 0 } dictionary displayGroupsShownIf { string a group x 1 } string displayName a prim bool hidden 1 } ) { int attribute 1 ( uiHints { string displayGroup a group string displayName an attr bool hidden 1 string shownIf x 2 } ) rel relationship ( uiHints { string displayGroup a group:a nested group string displayName a rel bool hidden 1 string shownIf x 3 } ) }这里relationship归入 a group 下的子组 a nested group。测试test_PrimHintsFromAsset验证了 prim 级displayGroupsExpanded与displayGroupsShownIf的读取testUsdUIHints.pytest_RelationshipHintsFromAsset验证了 relationship 的displayGroup a group:a nested group与shownIf x 3testUsdUIHints.py。嵌套组名中的:同时也是 USD 命名空间的通用分隔符这意味着显示组天然具备多级路径语义UI 可以据此渲染为折叠树。用布尔表达式实现条件显隐shownIf表达式基于SdfBooleanExpression见 booleanExpression.h。表达式文本在构造时被解析解析出错会得到一个空表达式且可通过GetParseError()获取错误信息。表达式支持的变量即为 prim 上的属性名求值时取属性的解析值resolved value。支持的运算符overview.md 完整列出运算符含义等于!不等于小于小于或等于大于大于或等于逻辑与\|\|逻辑或!一元逻辑非( )括号分组与优先级这些二元/一元操作在SdfBooleanExpression中对应BinaryOperatorEqualTo、NotEqualTo、LessThan、LessThanOrEqualTo、GreaterThan、GreaterThanOrEqualTo、And、Or与UnaryOperator::Not枚举并可用MakeVariable、MakeConstant、MakeBinaryOp、MakeUnaryOp在代码中程序化构造表达式见 booleanExpression.h。实战示例组合条件以下示例出自 overview.md演示了属性级shownIf与 prim 级displayGroupsShownIf的联合使用只有当 prim 的materialHardness解析值 2.0时Deformation parameters 显示组整体出现而组内的fractureAmount属性只有isFractured true时才显示def PrimUsingExpressions ( uiHints { dictionary displayGroupsShownIf { string Deformation parameters materialHardness 2.0 } } ) { float bendAmount 0.0 ( uiHints { string displayGroup Deformation parameters string displayName Bend amount } ) float bendDirection 0.0 ( uiHints { string displayGroup Deformation parameters string displayName Bend direction } ) float fractureAmount 0.0 ( uiHints { string displayGroup Deformation parameters string displayName Fracture amount string shownIf isFractured true } ) float materialHardness 10.0 bool isFractured false }高级表达式非与括号利用一元!与括号可以表达更复杂的逻辑。原文档给出的例子!(status active || level 5)仅在status不等于 active且level小于等于 5 时显示该属性。可见性判定规则易踩坑再次强调最终判定属性在 UI 中可见当且仅当hidden为 false 且shownIf表达式求值为 true。二者是或的隐藏条件——任一命中即隐藏。这在 overview.md 中有明确说明实现 UI 的消费方必须同时检查这两个 hint。属性顺序与显示组的关系PropertyHints 只决定属性归属哪个组不决定属性在组内/组间的排列顺序。属性默认按字典序返回Usd.Prim.GetProperties()要控制 UI 中的顺序需使用 prim 级reorder properties指令或Usd.Prim.SetPropertyOrder()API见 overview.mddef PropertyOrderPrimWithDisplayGroups ( uiHints { string displayName Example dictionary displayGroupsExpanded { bool Group A 1 bool Group B 1 } } ) { reorder properties [attribute4, attribute2, attribute1, attribute3] int attribute1 1 ( uiHints { string displayGroup Group B } ) int attribute2 2 int attribute3 3 ( uiHints { string displayGroup Group B } ) int attribute4 4 ( uiHints { string displayGroup Group A } ) }DCC 工具在布局时应遵循显示组按其被属性首次引用的位置放置组内属性按 prim 的 property order 排序。注意旧的displayGroupOrderprim 元数据字段已被视为弃用不应再与 property order / display group 相关 UI hints 混用见 overview.md。测试与验证仓库在 testUsdUIHints.py 中为 PropertyHints 提供了完整的自动化验证可作为消费方实现的参考基准test_RelationshipHintsFromAssetL228-L243验证 relationship 的displayGroup含嵌套与shownIf读取test_AttributeHintsFromAssetL206-L226验证 attribute 的displayGroup a group、shownIf x 2读取test_FallbacksL76-L122验证未授权时的回退值空字符串test_InvalidHintsL124-L156验证无效 hints 对象上 set 操作抛RuntimeErrortest_LegacyHintWritesL346-L369验证环境变量USDUI_WRITE_LEGACY_UI_HINTS开启时同步写入旧式字段。配套测试资产 hints.usda 中还包括一个HintlessPrim用于验证完全无提示属性的回退行为。与其它 Hints 的关系与建议ObjectHintsdisplayName、hidden作用于所有对象PropertyHints 示例中出现的这两个键实际属于 ObjectHints 层级仅与 PropertyHints 写在同一个uiHints字典中PrimHintsdisplayGroupsExpanded、displayGroupsShownIf控制显示组整体的展开状态与显示条件是 PropertyHints 的上层控制面AttributeHintsvalueLabels、valueLabelsOrder只适用于 attribute为属性的取值提供可读标签如把 1/2/3 显示为 low/med/high见 AttributeHints.mdrelationship 没有专属 hints直接复用 PropertyHints。编写建议优先使用UsdUI.PropertyHintsAPI 而非直接写元数据字典不要再用已弃用的UsdProperty::SetDisplayGroup/GetDisplayGroup等旧字段新写入统一进uiHints字典旧字段仅在回退读取时兼容将shownIf引用的属性值设计为显式的布尔/数值开关避免表达式依赖不存在的属性导致求值结果不确定。通过本文所述的displayGroup嵌套分组、shownIf布尔表达式以及属性顺序控制你可以在 .usda 资产中为 DCC 工具提供结构清晰、条件自适应的属性面板呈现方案——这正是 PropertyHints 在 OpenUSD 生态中承担的核心职责。【免费下载链接】OpenUSDUniversal Scene Description项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSD创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考