24#ifndef PXR_USD_IMAGING_USD_IMAGING_RESOLVED_ATTRIBUTE_CACHE_H
25#define PXR_USD_IMAGING_USD_IMAGING_RESOLVED_ATTRIBUTE_CACHE_H
30#include "pxr/usdImaging/usdImaging/api.h"
32#include "pxr/usd/usd/primRange.h"
34#include "pxr/usd/sdf/path.h"
41#include <tbb/concurrent_unordered_map.h>
44PXR_NAMESPACE_OPEN_SCOPE
68template<
typename Strategy,
typename ImplData=
bool>
69class UsdImaging_ResolvedAttributeCache
73 using _CacheMap = tbb::concurrent_unordered_map<UsdPrim, _Entry, TfHash>;
75 typedef typename Strategy::value_type value_type;
76 typedef typename Strategy::query_type query_type;
78 using ValueOverridesMap = TfHashMap<UsdPrim, value_type, TfHash>;
81 explicit UsdImaging_ResolvedAttributeCache(
83 ImplData *implData=
nullptr,
84 const ValueOverridesMap valueOverrides=ValueOverridesMap())
86 , _rootPath(
SdfPath::AbsoluteRootPath())
87 , _cacheVersion(_GetInitialCacheVersion())
88 , _valueOverrides(valueOverrides)
94 UsdImaging_ResolvedAttributeCache()
96 , _rootPath(
SdfPath::AbsoluteRootPath())
101 ~UsdImaging_ResolvedAttributeCache()
109 value_type GetValue(
const UsdPrim& prim)
const
114 "which is not within the specified root: %s",
116 _rootPath.GetString().c_str());
117 return Strategy::MakeDefault();
120 return *_GetValue(prim);
127 GetQuery(
const UsdPrim& prim)
const {
128 return &_GetCacheEntryForPrim(prim)->query;
134 _cacheVersion = _GetInitialCacheVersion();
144 if (Strategy::ValueMightBeTimeVarying()) {
166 void SetRootPath(
const SdfPath& rootPath) {
173 if (rootPath == _rootPath)
177 _rootPath = rootPath;
182 const SdfPath & GetRootPath()
const {
return _rootPath; }
194 void UpdateValueOverrides(
const ValueOverridesMap &valueOverrides,
195 const std::vector<UsdPrim> &overridesToRemove,
196 std::vector<SdfPath> *dirtySubtreeRoots)
200 if (valueOverrides.empty() && overridesToRemove.empty())
203 ValueOverridesMap valueOverridesToProcess;
204 SdfPathVector processedOverridePaths;
206 const UsdPrim &prim = it->first;
207 const value_type &value = it->second;
211 if (*_GetValue(prim) == value)
214 valueOverridesToProcess[prim] = value;
218 const UsdPrim &prim = it->first;
219 const value_type &value = it->second;
226 bool isDescendantOfProcessedOverride =
false;
227 for (
const SdfPath &processedPath : processedOverridePaths) {
229 isDescendantOfProcessedOverride =
true;
236 if (!isDescendantOfProcessedOverride) {
238 if (_Entry* entry = _GetCacheEntryForPrim(descendant)) {
239 entry->version = _GetInvalidVersion();
242 processedOverridePaths.push_back(prim.
GetPath());
243 dirtySubtreeRoots->push_back(prim.
GetPath());
247 _valueOverrides[prim] = value;
250 for (
const UsdPrim &prim : overridesToRemove) {
253 size_t numErased = _valueOverrides.erase(prim);
256 if (numErased == 0) {
260 bool isDescendantOfProcessedOverride =
false;
261 for (
const SdfPath &processedPath : processedOverridePaths) {
263 isDescendantOfProcessedOverride =
true;
270 if (!isDescendantOfProcessedOverride) {
272 if (_Entry* entry = _GetCacheEntryForPrim(descendant)) {
273 entry->version = _GetInvalidVersion();
276 dirtySubtreeRoots->push_back(prim.
GetPath());
277 processedOverridePaths.push_back(prim.
GetPath());
288 : value(Strategy::MakeDefault())
289 , version(_GetInitialEntryVersion())
292 _Entry(
const query_type & query_,
293 const value_type& value_,
302 tbb::atomic<unsigned> version;
306 unsigned _GetValidVersion()
const {
return _cacheVersion + 1; }
309 unsigned _GetInvalidVersion()
const {
return _cacheVersion - 1; }
312 static unsigned _GetInitialCacheVersion() {
return 1; }
313 static unsigned _GetInitialEntryVersion() {
314 return _GetInitialCacheVersion()-1;
319 value_type
const* _GetValue(
const UsdPrim& prim)
const;
322 _Entry* _GetCacheEntryForPrim(
const UsdPrim &prim)
const;
327 void _SetCacheEntryForPrim(
const UsdPrim &prim,
328 value_type
const& value,
329 _Entry* entry)
const;
334 mutable _CacheMap _cache;
342 tbb::atomic<unsigned> _cacheVersion;
345 ValueOverridesMap _valueOverrides;
351template<
typename Strategy,
typename ImplData>
353UsdImaging_ResolvedAttributeCache<Strategy,ImplData>::_SetCacheEntryForPrim(
355 value_type
const& value,
359 unsigned v = entry->version;
360 if (v < _cacheVersion
361 && entry->version.compare_and_swap(_cacheVersion, v) == v)
363 entry->value = value;
364 entry->version = _GetValidVersion();
366 while (entry->version != _GetValidVersion()) {
376template<
typename Strategy,
typename ImplData>
377typename UsdImaging_ResolvedAttributeCache<Strategy, ImplData>::_Entry*
378UsdImaging_ResolvedAttributeCache<Strategy, ImplData>::_GetCacheEntryForPrim(
381 typename _CacheMap::const_iterator it = _cache.find(prim);
382 if (it != _cache.end()) {
387 e.query = Strategy::MakeQuery(prim, _implData);
388 e.value = Strategy::MakeDefault();
389 e.version = _GetInvalidVersion();
390 return &(_cache.insert(
391 typename _CacheMap::value_type(prim, e)).first->second);
394template<
typename Strategy,
typename ImplData>
395typename UsdImaging_ResolvedAttributeCache<Strategy, ImplData>::value_type
const*
396UsdImaging_ResolvedAttributeCache<Strategy, ImplData>::_GetValue(
399 static value_type
const default_ = Strategy::MakeDefault();
405 _Entry* entry = _GetCacheEntryForPrim(prim);
406 if (entry->version == _GetValidVersion()) {
408 return &entry->value;
418 typename ValueOverridesMap::const_iterator it =
419 _valueOverrides.find(prim);
420 if (it != _valueOverrides.end()) {
421 _SetCacheEntryForPrim(prim, it->second, entry);
423 _SetCacheEntryForPrim(prim,
424 Strategy::Compute(
this, prim, &entry->query),
427 return &entry->value;
430PXR_NAMESPACE_CLOSE_SCOPE
439PXR_NAMESPACE_OPEN_SCOPE
441struct UsdImaging_XfStrategy;
442typedef UsdImaging_ResolvedAttributeCache<UsdImaging_XfStrategy> UsdImaging_XformCache;
444struct UsdImaging_XfStrategy {
449 bool ValueMightBeTimeVarying() {
return true; }
451 value_type MakeDefault() {
return GfMatrix4d(1); }
454 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
456 return query_type(xf);
463 Compute(UsdImaging_XformCache
const* owner,
465 query_type
const* query)
467 value_type xform = MakeDefault();
470 query->GetLocalTransformation(&xform, owner->GetTime());
472 return !query->GetResetXformStack()
473 ? (xform * (*owner->_GetValue(prim.
GetParent())))
481 ComputeTransform(
UsdPrim const& prim,
484 const TfHashMap<SdfPath, GfMatrix4d, SdfPath::Hash> &ctmOverrides)
490 while (p && p.
GetPath() != rootPath) {
491 const auto &overIt = ctmOverrides.find(p.
GetPath());
493 if (overIt != ctmOverrides.end()) {
494 ctm *= overIt->second;
497 if (xf.GetLocalTransformation(&localXf, &reset, time))
508PXR_NAMESPACE_CLOSE_SCOPE
516#include "pxr/usdImaging/usdImaging/debugCodes.h"
518PXR_NAMESPACE_OPEN_SCOPE
520struct UsdImaging_VisStrategy;
521using UsdImaging_VisCache =
522 UsdImaging_ResolvedAttributeCache<UsdImaging_VisStrategy>;
527struct UsdImaging_VisStrategy {
532 bool ValueMightBeTimeVarying() {
return true; }
535 value_type MakeDefault() {
return UsdGeomTokens->inherited; }
538 query_type MakeQuery(
UsdPrim const& prim,
bool *)
541 return query_type(xf.GetVisibilityAttr());
548 Compute(UsdImaging_VisCache
const* owner,
550 query_type
const* query)
552 value_type v = *owner->_GetValue(prim.
GetParent());
562 query->Get(&v, owner->GetTime());
579struct UsdImaging_PurposeStrategy;
580typedef UsdImaging_ResolvedAttributeCache<UsdImaging_PurposeStrategy>
581 UsdImaging_PurposeCache;
583struct UsdImaging_PurposeStrategy {
591 value_type MakeDefault() {
597 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
599 return query_type(im.GetPurposeAttr());
606 Compute(UsdImaging_PurposeCache
const* owner,
608 query_type
const* query)
614 return *(owner->_GetValue(prim.
GetParent()));
618 if (query->HasAuthoredValue()) {
620 query->Get(&info.purpose);
621 info.isInheritable =
true;
628 const value_type *v = owner->_GetValue(prim.
GetParent());
629 if (v->isInheritable) {
636 query->Get(&info.purpose);
642 ComputePurposeInfo(
UsdPrim const& prim)
648PXR_NAMESPACE_CLOSE_SCOPE
657PXR_NAMESPACE_OPEN_SCOPE
659struct UsdImaging_MaterialBindingImplData {
662 UsdImaging_MaterialBindingImplData(
const TfToken &materialPurpose):
663 _materialPurpose(materialPurpose)
668 ~UsdImaging_MaterialBindingImplData() {
673 const TfToken &GetMaterialPurpose()
const {
674 return _materialPurpose;
680 {
return _bindingsCache; }
685 {
return _collQueryCache; }
691 const TfToken _materialPurpose;
696struct UsdImaging_MaterialStrategy;
697typedef UsdImaging_ResolvedAttributeCache<UsdImaging_MaterialStrategy,
698 UsdImaging_MaterialBindingImplData>
699 UsdImaging_MaterialBindingCache;
701struct UsdImaging_MaterialStrategy {
712 using ImplData = UsdImaging_MaterialBindingImplData;
715 bool ValueMightBeTimeVarying() {
return false; }
717 value_type MakeDefault() {
return SdfPath(); }
720 query_type MakeQuery(
727 &implData->GetBindingsCache(),
728 &implData->GetCollectionQueryCache(),
729 implData->GetMaterialPurpose(),
745 Compute(UsdImaging_MaterialBindingCache
const* owner,
747 query_type
const* query)
749 TF_DEBUG(USDIMAGING_SHADERS).Msg(
"Looking for \"preview\" material "
764 ComputeMaterialPath(
UsdPrim const& prim, ImplData *implData) {
769 &implData->GetBindingsCache(),
770 &implData->GetCollectionQueryCache(),
771 implData->GetMaterialPurpose(),
784PXR_NAMESPACE_CLOSE_SCOPE
792PXR_NAMESPACE_OPEN_SCOPE
794struct UsdImaging_DrawModeStrategy;
795typedef UsdImaging_ResolvedAttributeCache<UsdImaging_DrawModeStrategy>
796 UsdImaging_DrawModeCache;
798struct UsdImaging_DrawModeStrategy
804 bool ValueMightBeTimeVarying() {
return false; }
809 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
811 return query_type(modelApi.GetModelDrawModeAttr());
818 Compute(UsdImaging_DrawModeCache
const* owner,
820 query_type
const* query)
842 ComputeDrawMode(
UsdPrim const& prim)
848PXR_NAMESPACE_CLOSE_SCOPE
856PXR_NAMESPACE_OPEN_SCOPE
858struct UsdImaging_PointInstancerIndicesStrategy;
859typedef UsdImaging_ResolvedAttributeCache<UsdImaging_PointInstancerIndicesStrategy>
860 UsdImaging_PointInstancerIndicesCache;
862struct UsdImaging_PointInstancerIndicesStrategy
867 typedef int query_type;
880 bool ValueMightBeTimeVarying() {
return true; }
882 value_type MakeDefault() {
return value_type(); }
885 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
891 Compute(UsdImaging_PointInstancerIndicesCache
const* owner,
893 query_type
const* query)
895 return ComputePerPrototypeIndices(prim, owner->GetTime());
905 VtIntArray protoIndices;
906 if (!pi.GetProtoIndicesAttr().Get(&protoIndices, time)) {
907 TF_WARN(
"Failed to read point instancer protoIndices");
911 std::vector<bool> mask = pi.ComputeMaskAtTime(time);
913 for (
size_t instanceId = 0; instanceId < protoIndices.size(); ++instanceId) {
914 size_t protoIndex = protoIndices[instanceId];
916 if (protoIndex >= v.size()) {
917 v.resize(protoIndex + 1);
920 if (mask.size() == 0 || mask[instanceId]) {
921 v[protoIndex].push_back(instanceId);
929PXR_NAMESPACE_CLOSE_SCOPE
936#include "pxr/imaging/hd/coordSys.h"
938PXR_NAMESPACE_OPEN_SCOPE
940struct UsdImaging_CoordSysBindingStrategy;
942typedef UsdImaging_ResolvedAttributeCache<UsdImaging_CoordSysBindingStrategy>
943 UsdImaging_CoordSysBindingCache;
945struct UsdImaging_CoordSysBindingStrategy
947 typedef std::vector<UsdShadeCoordSysAPI::Binding> UsdBindingVec;
948 typedef std::shared_ptr<UsdBindingVec> UsdBindingVecPtr;
949 typedef std::shared_ptr<SdfPathVector> IdVecPtr;
953 UsdBindingVecPtr usdBindingVecPtr;
955 typedef int query_type;
958 bool ValueMightBeTimeVarying() {
return false; }
961 value_type MakeDefault() {
966 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
972 Compute(UsdImaging_CoordSysBindingCache
const* owner,
974 query_type
const* query)
980 v = *owner->_GetValue(parentPrim);
983 auto _IterateLocalBindings = [&prim](
const UsdBindingVec &localBindings,
984 SdfPathVector &hdIds, UsdBindingVec &usdBindings) {
986 if (!prim.
GetStage()->GetPrimAtPath(
987 binding.coordSysPrimPath).IsValid()) {
990 TF_WARN(
"UsdImaging: Ignore coordinate system binding to "
991 "non-existent prim <%s>\n",
992 binding.coordSysPrimPath.GetText());
996 for (
size_t id = 0, n = hdIds.size();
id < n; ++
id) {
997 if (usdBindings[
id].name == binding.name) {
999 usdBindings[id] = binding;
1000 hdIds[id] = binding.bindingRelPath;
1007 usdBindings.push_back(binding);
1008 hdIds.push_back(binding.bindingRelPath);
1021 if (hasLocalBindings && !localBindings.empty()) {
1022 SdfPathVector hdIds;
1023 UsdBindingVec usdBindings;
1025 hdIds = *v.idVecPtr;
1027 if (v.usdBindingVecPtr) {
1028 usdBindings = *v.usdBindingVecPtr;
1030 _IterateLocalBindings(localBindings, hdIds, usdBindings);
1031 v.idVecPtr.reset(
new SdfPathVector(std::move(hdIds)));
1032 v.usdBindingVecPtr.reset(
new UsdBindingVec(std::move(usdBindings)));
1039PXR_NAMESPACE_CLOSE_SCOPE
1047PXR_NAMESPACE_OPEN_SCOPE
1049struct UsdImaging_NonlinearSampleCountStrategy;
1050typedef UsdImaging_ResolvedAttributeCache<
1051 UsdImaging_NonlinearSampleCountStrategy>
1052 UsdImaging_NonlinearSampleCountCache;
1054struct UsdImaging_NonlinearSampleCountStrategy
1056 typedef int value_type;
1061 static constexpr value_type invalidValue = -1;
1064 bool ValueMightBeTimeVarying() {
return true; }
1067 value_type MakeDefault() {
1068 return invalidValue;
1072 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
1074 return query_type(motionAPI.GetNonlinearSampleCountAttr());
1076 return query_type();
1081 Compute(UsdImaging_NonlinearSampleCountCache
const* owner,
1083 query_type
const* query)
1085 if (query->HasAuthoredValue()) {
1087 if (query->Get(&value, owner->GetTime())) {
1092 return *owner->_GetValue(prim.
GetParent());
1103PXR_NAMESPACE_CLOSE_SCOPE
1111PXR_NAMESPACE_OPEN_SCOPE
1113struct UsdImaging_BlurScaleStrategy;
1114typedef UsdImaging_ResolvedAttributeCache<UsdImaging_BlurScaleStrategy>
1115 UsdImaging_BlurScaleCache;
1117struct UsdImaging_BlurScaleStrategy
1128 static const value_type invalidValue;
1131 bool ValueMightBeTimeVarying() {
return true; }
1134 value_type MakeDefault() {
1135 return invalidValue;
1139 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
1141 return query_type(motionAPI.GetMotionBlurScaleAttr());
1143 return query_type();
1148 Compute(UsdImaging_BlurScaleCache
const* owner,
1150 query_type
const* query)
1152 if (query->HasAuthoredValue()) {
1154 if (query->Get(&value, owner->GetTime())) {
1155 return { value,
true };
1159 return *owner->_GetValue(prim.
GetParent());
1170PXR_NAMESPACE_CLOSE_SCOPE
1178PXR_NAMESPACE_OPEN_SCOPE
1180struct UsdImaging_InheritedPrimvarStrategy;
1181typedef UsdImaging_ResolvedAttributeCache<UsdImaging_InheritedPrimvarStrategy>
1182 UsdImaging_InheritedPrimvarCache;
1184struct UsdImaging_InheritedPrimvarStrategy
1186 struct PrimvarRecord {
1187 std::vector<UsdGeomPrimvar> primvars;
1190 typedef std::shared_ptr<PrimvarRecord> value_type;
1196 bool ValueMightBeTimeVarying() {
return false; }
1199 value_type MakeDefault() {
1200 return value_type();
1204 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
1209 value_type Compute(UsdImaging_InheritedPrimvarCache
const* owner,
1211 query_type
const* query)
1217 v = *owner->_GetValue(parentPrim);
1220 std::vector<UsdGeomPrimvar> primvars =
1221 query->FindIncrementallyInheritablePrimvars(
1222 v ? v->primvars : std::vector<UsdGeomPrimvar>());
1223 if (!primvars.empty()) {
1224 v = std::make_shared<PrimvarRecord>();
1225 v->primvars = std::move(primvars);
1226 v->variable =
false;
1239PXR_NAMESPACE_CLOSE_SCOPE
void WorkSwapDestroyAsync(T &obj)
Swap obj with a default-constructed T instance, return and arrange for the swapped-out instance to be...
Stores a 4x4 matrix of double elements.
A path value used to locate objects in layers or scenegraphs.
SDF_API const std::string & GetString() const
Return the string representation of this path as a std::string.
SDF_API const char * GetText() const
Returns the string representation of this path as a c string.
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
SDF_API bool IsAbsolutePath() const
Returns whether the path is absolute.
SDF_API bool HasPrefix(const SdfPath &prefix) const
Return true if both this path and prefix are not the empty path and this path has prefix as a prefix.
Token for efficient comparison, assignment, and hashing of known strings.
Object for efficiently making repeated queries for attribute values.
Base class for all prims that may require rendering or visualization of some sort.
USDGEOM_API PurposeInfo ComputePurposeInfo() const
Calculate the effective purpose information about this prim which includes final computed purpose val...
USDGEOM_API TfToken ComputeVisibility(UsdTimeCode const &time=UsdTimeCode::Default()) const
Calculate the effective visibility of this prim, as defined by its most ancestral authored "invisible...
UsdGeomModelAPI extends the generic UsdModelAPI schema with geometry specific concepts such as cached...
USDGEOM_API TfToken ComputeModelDrawMode(const TfToken &parentDrawMode=TfToken()) const
Calculate the effective model:drawMode of this prim.
UsdGeomMotionAPI encodes data that can live on any prim that may affect computations involving:
USDGEOM_API float ComputeMotionBlurScale(UsdTimeCode time=UsdTimeCode::Default()) const
Compute the inherited value of motion:blurScale at time, i.e.
USDGEOM_API int ComputeNonlinearSampleCount(UsdTimeCode time=UsdTimeCode::Default()) const
Compute the inherited value of nonlinearSampleCount at time, i.e.
Encodes vectorized instancing of multiple, potentially animated, prototypes (object/instance masters)...
Schema wrapper for UsdAttribute for authoring and introspecting attributes that are primvars.
USDGEOM_API bool ValueMightBeTimeVarying() const
Return true if it is possible, but not certain, that this primvar's value changes over time,...
UsdGeomPrimvarsAPI encodes geometric "primitive variables", as UsdGeomPrimvar, which interpolate acro...
SdfPath GetPath() const
Return the complete scene path to this object on its UsdStage, which may (UsdPrim) or may not (all ot...
USD_API UsdStageWeakPtr GetStage() const
Return the stage that owns the object, and to whose state and lifetime this object's validity is tied...
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
UsdPrim GetParent() const
Return this prim's parent prim.
bool IsPrototype() const
Return true if this prim is an instancing prototype prim, false otherwise.
bool IsInPrototype() const
Return true if this prim is a prototype prim or a descendant of a prototype prim, false otherwise.
An forward-iterable range that traverses a subtree of prims rooted at a given prim in depth-first ord...
A UsdRelationship creates dependencies between scenegraph objects by allowing a prim to target other ...
SdfPath GetPath() const
Shorthand for GetPrim()->GetPath().
UsdShadeCoordSysAPI provides a way to designate, name, and discover coordinate systems.
USDSHADE_API std::vector< Binding > GetLocalBindings() const
Get the list of coordinate system bindings local to this prim.
USDSHADE_API bool HasLocalBindings() const
Returns true if the prim has local coordinate system relationship exists.
A coordinate system binding.
UsdShadeMaterialBindingAPI is an API schema that provides an interface for binding materials to prims...
tbb::concurrent_unordered_map< SdfPath, std::unique_ptr< UsdCollectionAPI::MembershipQuery >, SdfPath::Hash > CollectionQueryCache
An unordered list of collection paths mapped to the associated collection's MembershipQuery object.
static USDSHADE_API const SdfPath GetResolvedTargetPathFromBindingRel(const UsdRelationship &bindingRel)
returns the path of the resolved target identified by bindingRel.
tbb::concurrent_unordered_map< SdfPath, std::unique_ptr< BindingsAtPrim >, SdfPath::Hash > BindingsCache
An unordered list of prim-paths mapped to the corresponding set of bindings at the associated prim.
USDSHADE_API UsdShadeMaterial ComputeBoundMaterial(BindingsCache *bindingsCache, CollectionQueryCache *collectionQueryCache, const TfToken &materialPurpose=UsdShadeTokens->allPurpose, UsdRelationship *bindingRel=nullptr, bool supportLegacyBindings=true) const
Computes the resolved bound material for this prim, for the given material purpose.
A Material provides a container into which multiple "render contexts" can add data that defines a "sh...
Represent a time value, which may be either numeric, holding a double value, or a sentinel value UsdT...
Represents an arbitrary dimensional rectangular container class.
#define TF_FOR_ALL(iter, c)
Macro for iterating over a container.
#define TF_DEBUG(enumVal)
Evaluate and print debugging message msg if enumVal is enabled for debugging.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
#define TF_WARN(...)
Issue a warning, but continue execution.
Value type containing information about a prim's computed effective purpose as well as storing whethe...
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
#define TRACE_FUNCTION()
Records a timestamp when constructed and a timespan event when destructed, using the name of the func...
USDGEOM_API TfStaticData< UsdGeomTokensType > UsdGeomTokens
A global variable with static, efficient TfTokens for use in all public USD API.