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" 38 #include <boost/functional/hash.hpp> 39 #include <tbb/concurrent_unordered_map.h> 42 PXR_NAMESPACE_OPEN_SCOPE
66 template<
typename Strategy,
typename ImplData=
bool>
67 class UsdImaging_ResolvedAttributeCache
71 typedef tbb::concurrent_unordered_map<
UsdPrim,
73 boost::hash<UsdPrim> > _CacheMap;
75 typedef typename Strategy::value_type value_type;
76 typedef typename Strategy::query_type query_type;
78 typedef TfHashMap<UsdPrim, value_type, boost::hash<UsdPrim> >
82 explicit UsdImaging_ResolvedAttributeCache(
84 ImplData *implData=
nullptr,
85 const ValueOverridesMap valueOverrides=ValueOverridesMap())
87 , _rootPath(
SdfPath::AbsoluteRootPath())
88 , _cacheVersion(_GetInitialCacheVersion())
89 , _valueOverrides(valueOverrides)
95 UsdImaging_ResolvedAttributeCache()
97 , _rootPath(
SdfPath::AbsoluteRootPath())
102 ~UsdImaging_ResolvedAttributeCache()
110 value_type GetValue(
const UsdPrim& prim)
const 116 "which is not within the specified root: %s",
118 _rootPath.GetString().c_str());
119 return Strategy::MakeDefault();
122 return *_GetValue(prim);
129 GetQuery(
const UsdPrim& prim)
const {
130 return &_GetCacheEntryForPrim(prim)->query;
136 _cacheVersion = _GetInitialCacheVersion();
146 if (Strategy::ValueMightBeTimeVarying()) {
168 void SetRootPath(
const SdfPath& rootPath) {
175 if (rootPath == _rootPath)
179 _rootPath = rootPath;
184 const SdfPath & GetRootPath()
const {
return _rootPath; }
196 void UpdateValueOverrides(
const ValueOverridesMap &valueOverrides,
197 const std::vector<UsdPrim> &overridesToRemove,
198 std::vector<SdfPath> *dirtySubtreeRoots)
202 if (valueOverrides.empty() && overridesToRemove.empty())
205 ValueOverridesMap valueOverridesToProcess;
206 SdfPathVector processedOverridePaths;
208 const UsdPrim &prim = it->first;
209 const value_type &value = it->second;
213 if (*_GetValue(prim) == value)
216 valueOverridesToProcess[prim] = value;
220 const UsdPrim &prim = it->first;
221 const value_type &value = it->second;
228 bool isDescendantOfProcessedOverride =
false;
229 for (
const SdfPath &processedPath : processedOverridePaths) {
231 isDescendantOfProcessedOverride =
true;
238 if (!isDescendantOfProcessedOverride) {
240 if (_Entry* entry = _GetCacheEntryForPrim(descendant)) {
241 entry->version = _GetInvalidVersion();
244 processedOverridePaths.push_back(prim.
GetPath());
245 dirtySubtreeRoots->push_back(prim.
GetPath());
249 _valueOverrides[prim] = value;
252 for (
const UsdPrim &prim : overridesToRemove) {
255 size_t numErased = _valueOverrides.erase(prim);
258 if (numErased == 0) {
262 bool isDescendantOfProcessedOverride =
false;
263 for (
const SdfPath &processedPath : processedOverridePaths) {
265 isDescendantOfProcessedOverride =
true;
272 if (!isDescendantOfProcessedOverride) {
274 if (_Entry* entry = _GetCacheEntryForPrim(descendant)) {
275 entry->version = _GetInvalidVersion();
278 dirtySubtreeRoots->push_back(prim.
GetPath());
279 processedOverridePaths.push_back(prim.
GetPath());
290 : value(Strategy::MakeDefault())
291 , version(_GetInitialEntryVersion())
294 _Entry(
const query_type & query_,
295 const value_type& value_,
304 tbb::atomic<unsigned> version;
308 unsigned _GetValidVersion()
const {
return _cacheVersion + 1; }
311 unsigned _GetInvalidVersion()
const {
return _cacheVersion - 1; }
314 static unsigned _GetInitialCacheVersion() {
return 1; }
315 static unsigned _GetInitialEntryVersion() {
316 return _GetInitialCacheVersion()-1;
321 value_type
const* _GetValue(
const UsdPrim& prim)
const;
324 _Entry* _GetCacheEntryForPrim(
const UsdPrim &prim)
const;
329 void _SetCacheEntryForPrim(
const UsdPrim &prim,
330 value_type
const& value,
331 _Entry* entry)
const;
336 mutable _CacheMap _cache;
344 tbb::atomic<unsigned> _cacheVersion;
347 ValueOverridesMap _valueOverrides;
353 template<
typename Strategy,
typename ImplData>
355 UsdImaging_ResolvedAttributeCache<Strategy,ImplData>::_SetCacheEntryForPrim(
357 value_type
const& value,
361 unsigned v = entry->version;
362 if (v < _cacheVersion
363 && entry->version.compare_and_swap(_cacheVersion, v) == v)
365 entry->value = value;
366 entry->version = _GetValidVersion();
368 while (entry->version != _GetValidVersion()) {
378 template<
typename Strategy,
typename ImplData>
379 typename UsdImaging_ResolvedAttributeCache<Strategy, ImplData>::_Entry*
380 UsdImaging_ResolvedAttributeCache<Strategy, ImplData>::_GetCacheEntryForPrim(
383 typename _CacheMap::const_iterator it = _cache.find(prim);
384 if (it != _cache.end()) {
389 e.query = Strategy::MakeQuery(prim, _implData);
390 e.value = Strategy::MakeDefault();
391 e.version = _GetInvalidVersion();
392 return &(_cache.insert(
393 typename _CacheMap::value_type(prim, e)).first->second);
396 template<
typename Strategy,
typename ImplData>
397 typename UsdImaging_ResolvedAttributeCache<Strategy, ImplData>::value_type
const*
398 UsdImaging_ResolvedAttributeCache<Strategy, ImplData>::_GetValue(
401 static value_type
const default_ = Strategy::MakeDefault();
407 _Entry* entry = _GetCacheEntryForPrim(prim);
408 if (entry->version == _GetValidVersion()) {
410 return &entry->value;
420 typename ValueOverridesMap::const_iterator it =
421 _valueOverrides.find(prim);
422 if (it != _valueOverrides.end()) {
423 _SetCacheEntryForPrim(prim, it->second, entry);
425 _SetCacheEntryForPrim(prim,
426 Strategy::Compute(
this, prim, &entry->query),
429 return &entry->value;
432 PXR_NAMESPACE_CLOSE_SCOPE
441 PXR_NAMESPACE_OPEN_SCOPE
443 struct UsdImaging_XfStrategy;
444 typedef UsdImaging_ResolvedAttributeCache<UsdImaging_XfStrategy> UsdImaging_XformCache;
446 struct UsdImaging_XfStrategy {
451 bool ValueMightBeTimeVarying() {
return true; }
453 value_type MakeDefault() {
return GfMatrix4d(1); }
456 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
458 return query_type(xf);
465 Compute(UsdImaging_XformCache
const* owner,
467 query_type
const* query)
469 value_type xform = MakeDefault();
472 query->GetLocalTransformation(&xform, owner->GetTime());
474 return !query->GetResetXformStack()
475 ? (xform * (*owner->_GetValue(prim.
GetParent())))
483 ComputeTransform(
UsdPrim const& prim,
486 const TfHashMap<SdfPath, GfMatrix4d, SdfPath::Hash> &ctmOverrides)
492 while (p && p.
GetPath() != rootPath) {
493 const auto &overIt = ctmOverrides.find(p.
GetPath());
495 if (overIt != ctmOverrides.end()) {
496 ctm *= overIt->second;
499 if (xf.GetLocalTransformation(&localXf, &reset, time))
510 PXR_NAMESPACE_CLOSE_SCOPE
518 #include "pxr/usdImaging/usdImaging/debugCodes.h" 520 PXR_NAMESPACE_OPEN_SCOPE
522 struct UsdImaging_VisStrategy;
523 using UsdImaging_VisCache =
524 UsdImaging_ResolvedAttributeCache<UsdImaging_VisStrategy>;
529 struct UsdImaging_VisStrategy {
534 bool ValueMightBeTimeVarying() {
return true; }
537 value_type MakeDefault() {
return UsdGeomTokens->inherited; }
540 query_type MakeQuery(
UsdPrim const& prim,
bool *)
543 return query_type(xf.GetVisibilityAttr());
550 Compute(UsdImaging_VisCache
const* owner,
552 query_type
const* query)
554 value_type v = *owner->_GetValue(prim.
GetParent());
564 query->Get(&v, owner->GetTime());
581 struct UsdImaging_PurposeStrategy;
582 typedef UsdImaging_ResolvedAttributeCache<UsdImaging_PurposeStrategy>
583 UsdImaging_PurposeCache;
585 struct UsdImaging_PurposeStrategy {
593 value_type MakeDefault() {
599 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
601 return query_type(im.GetPurposeAttr());
608 Compute(UsdImaging_PurposeCache
const* owner,
610 query_type
const* query)
616 return *(owner->_GetValue(prim.
GetParent()));
620 if (query->HasAuthoredValue()) {
622 query->Get(&info.purpose);
623 info.isInheritable =
true;
630 const value_type *v = owner->_GetValue(prim.
GetParent());
631 if (v->isInheritable) {
638 query->Get(&info.purpose);
644 ComputePurposeInfo(
UsdPrim const& prim)
650 PXR_NAMESPACE_CLOSE_SCOPE
659 PXR_NAMESPACE_OPEN_SCOPE
661 struct UsdImaging_MaterialBindingImplData {
664 UsdImaging_MaterialBindingImplData(
const TfToken &materialPurpose):
665 _materialPurpose(materialPurpose)
670 ~UsdImaging_MaterialBindingImplData() {
675 const TfToken &GetMaterialPurpose()
const {
676 return _materialPurpose;
682 {
return _bindingsCache; }
687 {
return _collQueryCache; }
693 const TfToken _materialPurpose;
698 struct UsdImaging_MaterialStrategy;
699 typedef UsdImaging_ResolvedAttributeCache<UsdImaging_MaterialStrategy,
700 UsdImaging_MaterialBindingImplData>
701 UsdImaging_MaterialBindingCache;
703 struct UsdImaging_MaterialStrategy {
707 using ImplData = UsdImaging_MaterialBindingImplData;
710 bool ValueMightBeTimeVarying() {
return false; }
712 value_type MakeDefault() {
return SdfPath(); }
715 query_type MakeQuery(
720 &implData->GetBindingsCache(),
721 &implData->GetCollectionQueryCache(),
722 implData->GetMaterialPurpose());
727 Compute(UsdImaging_MaterialBindingCache
const* owner,
729 query_type
const* query)
731 TF_DEBUG(USDIMAGING_SHADERS).Msg(
"Looking for \"preview\" material " 734 SdfPath binding = query->GetPath();
748 ComputeMaterialPath(
UsdPrim const& prim, ImplData *implData) {
752 ComputeBoundMaterial(&implData->GetBindingsCache(),
753 &implData->GetCollectionQueryCache(),
754 implData->GetMaterialPurpose())) {
755 return mat.GetPath();
761 PXR_NAMESPACE_CLOSE_SCOPE
769 PXR_NAMESPACE_OPEN_SCOPE
771 struct UsdImaging_DrawModeStrategy;
772 typedef UsdImaging_ResolvedAttributeCache<UsdImaging_DrawModeStrategy>
773 UsdImaging_DrawModeCache;
775 struct UsdImaging_DrawModeStrategy
781 bool ValueMightBeTimeVarying() {
return false; }
786 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
788 return query_type(modelApi.GetModelDrawModeAttr());
795 Compute(UsdImaging_DrawModeCache
const* owner,
797 query_type
const* query)
819 ComputeDrawMode(
UsdPrim const& prim)
825 PXR_NAMESPACE_CLOSE_SCOPE
833 PXR_NAMESPACE_OPEN_SCOPE
835 struct UsdImaging_PointInstancerIndicesStrategy;
836 typedef UsdImaging_ResolvedAttributeCache<UsdImaging_PointInstancerIndicesStrategy>
837 UsdImaging_PointInstancerIndicesCache;
839 struct UsdImaging_PointInstancerIndicesStrategy
844 typedef int query_type;
857 bool ValueMightBeTimeVarying() {
return true; }
859 value_type MakeDefault() {
return value_type(); }
862 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
868 Compute(UsdImaging_PointInstancerIndicesCache
const* owner,
870 query_type
const* query)
872 return ComputePerPrototypeIndices(prim, owner->GetTime());
882 VtIntArray protoIndices;
883 if (!pi.GetProtoIndicesAttr().Get(&protoIndices, time)) {
884 TF_WARN(
"Failed to read point instancer protoIndices");
888 std::vector<bool> mask = pi.ComputeMaskAtTime(time);
890 for (
size_t instanceId = 0; instanceId < protoIndices.size(); ++instanceId) {
891 size_t protoIndex = protoIndices[instanceId];
893 if (protoIndex >= v.size()) {
894 v.resize(protoIndex + 1);
897 if (mask.size() == 0 || mask[instanceId]) {
898 v[protoIndex].push_back(instanceId);
906 PXR_NAMESPACE_CLOSE_SCOPE
913 #include "pxr/imaging/hd/coordSys.h" 915 PXR_NAMESPACE_OPEN_SCOPE
917 struct UsdImaging_CoordSysBindingImplData {
923 struct UsdImaging_CoordSysBindingStrategy;
925 typedef UsdImaging_ResolvedAttributeCache<
926 UsdImaging_CoordSysBindingStrategy,
927 UsdImaging_CoordSysBindingImplData>
928 UsdImaging_CoordSysBindingCache;
930 struct UsdImaging_CoordSysBindingStrategy
932 using ImplData = UsdImaging_CoordSysBindingImplData;
934 typedef std::vector<UsdShadeCoordSysAPI::Binding> UsdBindingVec;
935 typedef std::shared_ptr<UsdBindingVec> UsdBindingVecPtr;
936 typedef std::shared_ptr<SdfPathVector> IdVecPtr;
940 UsdBindingVecPtr usdBindingVecPtr;
949 return implData->usdToHydraPath(binding.bindingRelPath);
954 bool ValueMightBeTimeVarying() {
return false; }
957 value_type MakeDefault() {
962 query_type MakeQuery(
UsdPrim const& prim, ImplData *implData) {
968 Compute(UsdImaging_CoordSysBindingCache
const* owner,
970 query_type
const* query)
973 if (query->coordSysAPI) {
976 v = *owner->_GetValue(parentPrim);
979 if (query->coordSysAPI.HasLocalBindings()) {
981 UsdBindingVec usdBindings;
985 if (v.usdBindingVecPtr) {
986 usdBindings = *v.usdBindingVecPtr;
988 for (
auto const& binding:
989 query->coordSysAPI.GetLocalBindings()) {
990 if (!prim.
GetStage()->GetPrimAtPath(
991 binding.coordSysPrimPath).IsValid()) {
994 TF_WARN(
"UsdImaging: Ignoring coordinate system " 995 "binding to non-existent prim <%s>\n",
996 binding.coordSysPrimPath.
GetText());
1000 for (
size_t i=0, n=hdIds.size(); i<n; ++i) {
1001 if (usdBindings[i].name == binding.name) {
1003 usdBindings[i] = binding;
1004 hdIds[i] = query->_IdForBinding(binding);
1011 usdBindings.push_back(binding);
1012 hdIds.push_back(query->_IdForBinding(binding));
1015 v.idVecPtr.reset(
new SdfPathVector(hdIds));
1016 v.usdBindingVecPtr.reset(
new UsdBindingVec(usdBindings));
1023 PXR_NAMESPACE_CLOSE_SCOPE
1031 PXR_NAMESPACE_OPEN_SCOPE
1033 struct UsdImaging_NonlinearSampleCountStrategy;
1034 typedef UsdImaging_ResolvedAttributeCache<
1035 UsdImaging_NonlinearSampleCountStrategy>
1036 UsdImaging_NonlinearSampleCountCache;
1038 struct UsdImaging_NonlinearSampleCountStrategy
1040 typedef int value_type;
1045 static constexpr value_type invalidValue = -1;
1048 bool ValueMightBeTimeVarying() {
return true; }
1051 value_type MakeDefault() {
1052 return invalidValue;
1056 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
1058 return query_type(motionAPI.GetNonlinearSampleCountAttr());
1060 return query_type();
1065 Compute(UsdImaging_NonlinearSampleCountCache
const* owner,
1067 query_type
const* query)
1069 if (query->HasAuthoredValue()) {
1071 if (query->Get(&value, owner->GetTime())) {
1076 return *owner->_GetValue(prim.
GetParent());
1087 PXR_NAMESPACE_CLOSE_SCOPE
1095 PXR_NAMESPACE_OPEN_SCOPE
1097 struct UsdImaging_BlurScaleStrategy;
1098 typedef UsdImaging_ResolvedAttributeCache<UsdImaging_BlurScaleStrategy>
1099 UsdImaging_BlurScaleCache;
1101 struct UsdImaging_BlurScaleStrategy
1112 static const value_type invalidValue;
1115 bool ValueMightBeTimeVarying() {
return true; }
1118 value_type MakeDefault() {
1119 return invalidValue;
1123 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
1125 return query_type(motionAPI.GetMotionBlurScaleAttr());
1127 return query_type();
1132 Compute(UsdImaging_BlurScaleCache
const* owner,
1134 query_type
const* query)
1136 if (query->HasAuthoredValue()) {
1138 if (query->Get(&value, owner->GetTime())) {
1139 return { value,
true };
1143 return *owner->_GetValue(prim.
GetParent());
1154 PXR_NAMESPACE_CLOSE_SCOPE
1162 PXR_NAMESPACE_OPEN_SCOPE
1164 struct UsdImaging_InheritedPrimvarStrategy;
1165 typedef UsdImaging_ResolvedAttributeCache<UsdImaging_InheritedPrimvarStrategy>
1166 UsdImaging_InheritedPrimvarCache;
1168 struct UsdImaging_InheritedPrimvarStrategy
1170 struct PrimvarRecord {
1171 std::vector<UsdGeomPrimvar> primvars;
1174 typedef std::shared_ptr<PrimvarRecord> value_type;
1180 bool ValueMightBeTimeVarying() {
return false; }
1183 value_type MakeDefault() {
1184 return value_type();
1188 query_type MakeQuery(
UsdPrim const& prim,
bool *) {
1193 value_type Compute(UsdImaging_InheritedPrimvarCache
const* owner,
1195 query_type
const* query)
1201 v = *owner->_GetValue(parentPrim);
1204 std::vector<UsdGeomPrimvar> primvars =
1205 query->FindIncrementallyInheritablePrimvars(
1206 v ? v->primvars : std::vector<UsdGeomPrimvar>());
1207 if (!primvars.empty()) {
1208 v = std::make_shared<PrimvarRecord>();
1209 v->primvars = std::move(primvars);
1210 v->variable =
false;
1223 PXR_NAMESPACE_CLOSE_SCOPE
UsdShadeCoordSysAPI provides a way to designate, name, and discover coordinate systems.
UsdGeomModelAPI extends the generic UsdModelAPI schema with geometry specific concepts such as cached...
USD_API UsdStageWeakPtr GetStage() const
Return the stage that owns the object, and to whose state and lifetime this object's validity is tied...
Object for efficiently making repeated queries for attribute values.
#define TF_WARN(...)
Issue a warning, but continue execution.
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.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
SDF_API const char * GetText() const
Returns the string representation of this path as a c string.
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.
bool IsInPrototype() const
Return true if this prim is a prototype prim or a descendant of a prototype prim, false otherwise.
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.
A coordinate system binding.
UsdShadeMaterialBindingAPI is an API schema that provides an interface for binding materials to prims...
UsdGeomPrimvarsAPI encodes geometric "primitive variables", as UsdGeomPrimvar, which interpolate acro...
USDGEOM_API PurposeInfo ComputePurposeInfo() const
Calculate the effective purpose information about this prim which includes final computed purpose val...
USDGEOM_API int ComputeNonlinearSampleCount(UsdTimeCode time=UsdTimeCode::Default()) const
Compute the inherited value of nonlinearSampleCount at time, i.e.
Token for efficient comparison, assignment, and hashing of known strings.
#define TF_FOR_ALL(iter, c)
Macro for iterating over a container.
Stores a 4x4 matrix of double elements.
Represent a time value, which may be either numeric, holding a double value, or a sentinel value UsdT...
USDGEOM_API TfStaticData< UsdGeomTokensType > UsdGeomTokens
A global variable with static, efficient TfTokens for use in all public USD API.
UsdPrim GetParent() const
Return this prim's parent prim.
Value type containing information about a prim's computed effective purpose as well as storing whethe...
#define TRACE_FUNCTION()
Records a timestamp when constructed and a timespan event when destructed, using the name of the func...
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...
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Represents an arbitrary dimensional rectangular container class.
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.
#define TF_DEBUG(enumVal)
Evaluate and print debugging message msg if enumVal is enabled for debugging.
UsdGeomMotionAPI encodes data that can live on any prim that may affect computations involving:
SDF_API bool IsAbsolutePath() const
Returns whether the path is absolute.
An forward-iterable range that traverses a subtree of prims rooted at a given prim in depth-first ord...
USDSHADE_API UsdShadeMaterial ComputeBoundMaterial(BindingsCache *bindingsCache, CollectionQueryCache *collectionQueryCache, const TfToken &materialPurpose=UsdShadeTokens->allPurpose, UsdRelationship *bindingRel=nullptr) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
USDGEOM_API TfToken ComputeModelDrawMode(const TfToken &parentDrawMode=TfToken()) const
Calculate the effective model:drawMode of this prim.
bool IsPrototype() const
Return true if this prim is an instancing prototype prim, false otherwise.
A Material provides a container into which multiple "render targets" can add data that defines a "sha...
Encodes vectorized instancing of multiple, potentially animated, prototypes (object/instance masters)...
Schema wrapper for UsdAttribute for authoring and introspecting attributes that are primvars.
void WorkSwapDestroyAsync(T &obj)
Swap obj with a default-constructed T instance, return and arrange for the swapped-out instance to be...
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Base class for all prims that may require rendering or visualization of some sort.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
SdfPath GetPath() const
Return the complete scene path to this object on its UsdStage, which may (UsdPrim) or may not (all ot...
USDGEOM_API bool ValueMightBeTimeVarying() const
Return true if it is possible, but not certain, that this primvar's value changes over time,...
USDGEOM_API float ComputeMotionBlurScale(UsdTimeCode time=UsdTimeCode::Default()) const
Compute the inherited value of motion:blurScale at time, i.e.