ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

OpenUSD UsdUI AttributeHints 完全指南:用 valueLabels 与 valueLabelsOrder 定制属性值的 UI 展示

OpenUSD UsdUI AttributeHints 完全指南:用 valueLabels 与 valueLabelsOrder 定制属性值的 UI 展示 OpenUSD UsdUI AttributeHints 完全指南用 valueLabels 与 valueLabelsOrder 定制属性值的 UI 展示【免费下载链接】OpenUSDUniversal Scene Description项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSDAttributeHints 是 OpenUSDUsdUI领域为属性Attribute提供的 UI 提示机制用于把属性的底层数值映射为对用户友好的标签并控制这些标签在界面中的展示顺序。本篇指南以 pxr/usd/usdUI/userDoc/AttributeHints.md 为核心结合 attributeHints.h 等源码与测试用例帮助你完整掌握属性级 UI 提示的声明语法、UsdUIAttributeHintsAPI 用法及与 ObjectHints/PropertyHints 的配合方式从而让 DCC 工具或自研应用的面板更贴近美术与 TD 的使用习惯。AttributeHints 在 UsdUI UI Hints 体系中的定位在 OpenUSD 中UsdUI除了提供节点图Node Graph、无障碍访问Accessibility等能力外还提供了一组schema-like的 UI 提示 API用于描述 Prim 或属性在 DCC 工具及应用程序界面中应如何呈现。整体脉络可参考 pxr/usd/usdUI/userDoc/overview.mdUI Hints 目前划分为四组ObjectHints适用于任何 Prim 或属性的通用提示如displayName界面显示名、hidden界面中是否隐藏。PrimHintsPrim 级提示如显示组display groups如何、何时展示displayGroupsExpanded、displayGroupsShownIf。PropertyHints属性级提示如属性所属的显示组displayGroup、条件显示表达式shownIf。AttributeHints属性级提示如属性值的 UI 标签valueLabels及标签的展示顺序valueLabelsOrder。由于没有只适用于关系Relationship的专属提示因此不存在 RelationshipHints 分组。需要特别强调的是UI Hints 只是建议最终如何呈现完全由实现 UI 的工具或应用决定。AttributeHints 的独特价值在于它专门解决属性底层数值与用户可见文案之间的翻译问题。例如一个priority为int类型的属性底层存储的是1/2/3但界面上应该显示 very low / med / high 这样的可读标签——这正是 AttributeHints 的核心应用场景。AttributeHints 字段详解根据 pxr/usd/usdUI/userDoc/AttributeHints.mdAttributeHints 一共包含两个字段。valueLabelsUSD 类型dictionary含义以标签名为键、属性值为值的字典将 UI 中呈现给用户的标签映射到底层属性值。dictionary valueLabels { int high 3 int very low 1 int med 2 }从源码实现看attributeHints.cppGetValueLabels()通过UsdAttribute::GetMetadataByDictKey(UsdUIHintKeys-UIHints, UsdUIHintKeys-ValueLabels, ...)读取uiHints元数据字典中的valueLabels键SetValueLabels()则调用SetMetadataByDictKey写入。源码注释还指出一个细节由于该字段是 dictionary 类型其合成值composed value是所有相关编辑目标edit targets上条目的并集覆盖是按条目而非整个字典进行——这意味着通过 Layer 分层可以只覆盖某个标签而不必整体重写字典。valueLabelsOrderUSD 类型token[]含义一个 token 数组指示各 value label 在 UI 中的展示顺序典型用于下拉列表drop-down等需要按序列展示标签的 UI 元素。token[] valueLabelsOrder [very low, med, high]对应地GetValueLabelsOrder()/SetValueLabelsOrder()在 attributeHints.cpp 中同样是围绕uiHints字典中的ValueLabelsOrder键进行读写。注意对于string或token类型的属性应优先使用allowedTokens属性元数据来声明允许的 token 值如果同时使用valueLabels与valueLabelsOrder务必保证 UI 提示中的标签值与allowedTokens集合一致。此外属性还支持值范围限制value limits可结合属性 UI 提示在界面中向用户反馈合法取值区间详见UsdAttributeLimits。完整示例为属性值添加标签与排序原文档给出的最小完整示例展示了一个带priority属性的 Prim3 个数值被映射为 3 个标签并指定了标签的 UI 展示顺序。def PrimWithAttributesWithLabels ( uiHints { # UI hints from ObjectHints string displayName Example Prim bool hidden 0 } ) { int priority 1 ( uiHints { string displayName priority bool hidden 0 dictionary valueLabels { int high 3 int very low 1 int med 2 } token[] valueLabelsOrder [very low, med, high] } ) }要点Prim 上的uiHints存放的是 ObjectHints 字段displayName、hidden属性上的uiHints同时容纳 ObjectHintsdisplayName、hidden与 AttributeHints 字段valueLabels、valueLabelsOrdervalueLabels的键标签名若含空格需要用双引号包裹如int very low 1valueLabelsOrder数组中的 token 必须与valueLabels的键一一对应以便 UI 按指定顺序展示。该示例在 UI 中的呈现效果可参考文档自带的 mock-up 图uihints-attributehints.svg界面中的下拉列表展示了 very low / med / high 三个可选项。源码级解析UsdUIAttributeHints 的 API 与继承链AttributeHints 在代码层面对应UsdUIAttributeHints类attributeHints.h。它被描述为 schema-like 包装器虽然它解释的是核心对象类型UsdAttribute上的字段但它并非正式 schema也不继承UsdSchemaBase而是通过操作uiHints元数据字典提供便捷 API。从类定义attributeHints.h可以看到继承与能力分层UsdUIAttributeHints └─ UsdUIPropertyHints # displayGroup / shownIf └─ UsdUIObjectHints # displayName / hidden也就是说属性级提示天然继承了对象级与属性级的能力与文档中属性也能访问 ObjectHints 与 PropertyHints 的提示的描述完全对应。UsdUIAttributeHints对外提供的主要方法方法说明GetValueLabels()返回标签字典将 UI 标签关联到底层属性值SetValueLabels(const VtDictionary)写入标签字典成功返回trueGetValueLabelsOrder()返回标签展示顺序的 token 数组SetValueLabelsOrder(const VtTokenArray)写入标签顺序成功返回trueApplyValueLabel(const std::string label)将指定标签对应的值直接写入属性若标签不在字典中返回false其中ApplyValueLabel()的实现attributeHints.cpp值得关注它会先用标签名构造uiHints字典中的子键路径从valueLabels中取出对应值再通过UsdAttribute::Set(value)把该值写到属性上。这为 UI 提供了一种标准交互闭环用户点选某个标签 → 工具调用ApplyValueLabel(label)→ 属性被自动赋予对应的底层数值无需 UI 层自己去查字典翻译。在 Python 中可通过UsdUI.AttributeHints(attr)使用同样的 APIfrom pxr import Usd, UsdUI stage Usd.Stage.CreateNew(labels.usda) prim stage.DefinePrim(/PrimWithAttributesWithLabels) attr prim.CreateAttribute(priority, Sdf.ValueTypeNames.Int) attr.Set(1) hints UsdUI.AttributeHints(attr) hints.SetValueLabels({very low: 1, med: 2, high: 3}) hints.SetValueLabelsOrder([very low, med, high]) # 用户选中 high 后属性值自动变为 3 hints.ApplyValueLabel(high) print(attr.Get()) # 3回退值与默认行为注意构造函数与回退语义默认构造的UsdUIAttributeHints()是无效对象对其调用 set 类操作会报错TF_CODING_ERRORget 类操作返回回退值。具体回退值在 testUsdUIHints.py 中有明确断言未编写任何提示的属性GetValueLabels()返回{}、GetValueLabelsOrder()返回[]、GetDisplayGroup()返回、GetShownIf()返回、GetDisplayName()返回、GetHidden()返回False。测试资产佐证真实场景中的组合用法仓库自带的测试资产 hints.usda 完整演示了 AttributeHints 与 ObjectHints、PropertyHints 在同一属性上的组合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 dictionary valueLabels { int high 3 int low 1 int med 2 } token[] valueLabelsOrder [low, med, high] } ) token[] tokenArrayAttr [] ( uiHints { dictionary valueLabels { token[] foo [bar, baz] token[] bleep [bloop, blorp] } } ) }从中可以观察到标签值不限于标量valueLabels的值可以是任意 VtValue包括token[]数组——tokenArrayAttr把一组枚举选项[bar, baz]映射为一个标签foo多级提示可以叠加同一属性上displayGroup归属显示组、displayName显示名、hidden隐藏、shownIf条件显示、valueLabels/valueLabelsOrder值标签可同时编写、互不冲突。对应的测试用例 testUsdUIHints.py 验证了从资产读取提示的完整链路UsdUI.AttributeHints(attr)能同时拿到valueLabels {low:1, med:2, high:3}、valueLabelsOrder [low,med,high]、displayGroup a group、shownIf x 2、displayName an attr、hidden True。测试还覆盖了两个值得注意的行为testUsdUIHints.pyApplyValueLabel(label)会逐一把标签对应的值写入属性且对不存在的标签返回False且不修改属性值no-op对无效提示对象调用任何 set 方法都会抛出RuntimeErrortestUsdUIHints.py。与相关提示的配合显示组、条件表达式与向后兼容AttributeHints 在实际工程中几乎总是与其他 UI 提示协同工作相关的三个配套主题同样记录在 overview.md 中。显示组Display Groups与属性排序属性通过 PropertyHints 的displayGroup归属到某个显示组例如hints.SetDisplayGroup(Custom Properties)组名可用:嵌套如GroupA:NestedGroup表示NestedGroup是GroupA的子组。Prim 可用displayGroupsExpanded默认展开/折叠和displayGroupsShownIf条件显示控制组的呈现细节见 PrimHints.md。属性的整体展示顺序由 Prim 的reorder properties语句或Usd.Prim.SetPropertyOrder()API 控制DCC 工具应结合属性顺序来排布显示组按属性首次引用位置放置组、组内按属性顺序排列。条件表达式Boolean ExpressionsshownIfPropertyHints与displayGroupsShownIfPrimHints使用基于SdfBooleanExpression的布尔表达式字符串通常是测试所在 Prim 内某个属性的解析值例如materialHardness 2.0、isFractured true。支持的运算符包括、!、、、、、、||以及一元!与括号分组如!(status \active\ || level 5)。注意hidden对象级提示总是与shownIf一起生效只要shownIf求值为假或hidden为真属性就不会显示。向后兼容displayName、hidden、displayGroup曾经是可以单独编写的元数据字段通过UsdObject与UsdProperty。UI Hints API 在uiHints字典中未编写对应值时会回退查找这些旧字段以保证兼容但官方建议今后统一使用 UI Hints API 或uiHints字典不要再单独编写这些字段详见 overview.md 中的说明。同样地旧的displayGroupOrderPrim 元数据字段已被视为废弃不应再与属性顺序及显示组相关 UI 提示混用。最佳实践小结标签键与允许值保持一致对string/token属性先用allowedTokens声明允许值再确保valueLabels/valueLabelsOrder与其一致避免 UI 出现无意义的标签。优先使用 API 而非直接读元数据直接GetMetadata(uiHints)在未编写时返回None而 API如GetDisplayName()会返回合理的回退值空字符串、False、空字典/数组可省去大量判空逻辑。交互闭环交给ApplyValueLabelUI 选中标签后直接调用ApplyValueLabel(label)写入属性值由库保证取值的正确性。分层覆盖按条目生效valueLabels是字典跨 Layer 的覆盖按条目进行需要局部覆写某个标签时不必复制整个字典。组合而非替代valueLabels只解决值 ↔ 标签翻译与顺序结合displayGroup归类、shownIf条件显示、displayGroupsExpanded默认展开态才能构成完整的属性面板体验。【免费下载链接】OpenUSDUniversal Scene Description项目地址: https://gitcode.com/GitHub_Trending/ope/OpenUSD创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表