7#ifndef PXR_USD_USD_PRIM_DATA_H
8#define PXR_USD_USD_PRIM_DATA_H
13#include "pxr/usd/usd/api.h"
16#include "pxr/usd/usd/primDefinition.h"
17#include "pxr/usd/usd/primTypeInfo.h"
21#include "pxr/base/tf/pointerAndBits.h"
24#include "pxr/usd/sdf/path.h"
30PXR_NAMESPACE_OPEN_SCOPE
67 const SdfPath &GetPath()
const {
return _path; }
69 const TfToken &GetName()
const {
return GetPath().GetNameToken(); }
71 UsdStage *GetStage()
const {
return _stage; }
75 return _primTypeInfo->GetPrimDefinition();
80 const TfToken& GetTypeName()
const {
81 return _primTypeInfo->GetTypeName();
86 return *_primTypeInfo;
90 bool IsPseudoRoot()
const {
return _flags[Usd_PrimPseudoRootFlag]; }
94 bool IsActive()
const {
return _flags[Usd_PrimActiveFlag]; }
99 bool IsLoaded()
const {
return _flags[Usd_PrimLoadedFlag]; }
103 bool IsModel()
const {
return _flags[Usd_PrimModelFlag]; }
108 bool IsGroup()
const {
return _flags[Usd_PrimGroupFlag]; }
110 bool IsComponent()
const {
return _flags[Usd_PrimComponentFlag]; }
113 bool IsSubComponent()
const;
116 bool IsAbstract()
const {
return _flags[Usd_PrimAbstractFlag]; }
120 bool IsDefined()
const {
return _flags[Usd_PrimDefinedFlag]; }
124 bool HasDefiningSpecifier()
const {
125 return _flags[Usd_PrimHasDefiningSpecifierFlag];
129 bool HasClassSpecifier()
const {
130 return _flags[Usd_PrimHasClassSpecifierFlag];
134 bool HasPayload()
const {
return _flags[Usd_PrimHasPayloadFlag]; }
139 bool MayHaveOpinionsInClips()
const {
return _flags[Usd_PrimClipsFlag]; }
151 Usd_PrimDataConstPtr GetParent()
const;
190 Usd_PrimDataPtr GetFirstChild()
const {
return _firstChild; }
193 Usd_PrimDataPtr GetNextSibling()
const {
194 return !_nextSiblingOrParent.BitsAs<
bool>() ?
195 _nextSiblingOrParent.Get() :
nullptr;
201 Usd_PrimDataPtr GetParentLink()
const {
202 return _nextSiblingOrParent.BitsAs<
bool>() ?
203 _nextSiblingOrParent.Get() :
nullptr;
209 inline Usd_PrimDataPtr GetNextPrim()
const {
210 if (Usd_PrimDataPtr sibling = GetNextSibling())
212 for (Usd_PrimDataPtr p = GetParentLink(); p; p = p->GetParentLink()) {
213 if (Usd_PrimDataPtr sibling = p->GetNextSibling())
222 USD_API Usd_PrimDataConstPtr
223 GetPrimDataAtPathOrInPrototype(
const SdfPath &path)
const;
231 bool IsInstance()
const {
return _flags[Usd_PrimInstanceFlag]; }
234 bool IsPrototype()
const {
235 return IsInPrototype() && GetPath().IsRootPrimPath();
240 bool IsInPrototype()
const {
return _flags[Usd_PrimPrototypeFlag]; }
244 USD_API Usd_PrimDataConstPtr GetPrototype()
const;
257 void _ComposeAndCacheFlags(
258 Usd_PrimDataConstPtr parent,
bool isPrototypePrim);
261 friend class Usd_PrimFlagsPredicate;
262 const Usd_PrimFlagBits &_GetFlags()
const {
274 void _SetSiblingLink(Usd_PrimDataPtr sibling) {
275 _nextSiblingOrParent.Set(sibling,
false);
278 void _SetParentLink(Usd_PrimDataPtr parent) {
279 _nextSiblingOrParent.Set(parent,
true);
284 _flags[Usd_PrimDeadFlag] =
true;
286 _primIndex =
nullptr;
290 bool _IsDead()
const {
return _flags[Usd_PrimDeadFlag]; }
294 void _SetMayHaveOpinionsInClips(
bool hasClips) {
295 _flags[Usd_PrimClipsFlag] = hasClips;
298 inline class Usd_PrimDataSiblingIterator _ChildrenBegin() const;
299 inline class Usd_PrimDataSiblingIterator _ChildrenEnd() const;
301 inline class Usd_PrimDataSubtreeIterator _SubtreeBegin() const;
302 inline class Usd_PrimDataSubtreeIterator _SubtreeEnd() const;
309 Usd_PrimData *_firstChild;
311 mutable std::atomic<int64_t> _refCount;
312 Usd_PrimFlagBits _flags;
315 friend void TfDelegatedCountIncrement(
const Usd_PrimData *prim)
noexcept {
316 prim->_refCount.fetch_add(1, std::memory_order_relaxed);
318 friend void TfDelegatedCountDecrement(
const Usd_PrimData *prim)
noexcept {
319 if (prim->_refCount.fetch_sub(1, std::memory_order_release) == 1) {
322 std::atomic_thread_fence(std::memory_order_acquire);
328 friend void Usd_ThrowExpiredPrimAccessError(Usd_PrimData
const *p);
330 Usd_DescribePrimData(
const Usd_PrimData *p,
SdfPath const &proxyPrimPath);
332 friend inline bool Usd_IsDead(Usd_PrimData
const *p) {
341class Usd_PrimDataSiblingIterator {
342 using _UnderylingIterator = Usd_PrimData*;
344 using iterator_category = std::forward_iterator_tag;
345 using value_type = Usd_PrimData*;
346 using reference = Usd_PrimData*;
347 using pointer = void;
348 using difference_type = std::ptrdiff_t;
351 Usd_PrimDataSiblingIterator() =
default;
353 reference operator*()
const {
return _underlyingIterator; }
356 Usd_PrimDataSiblingIterator& operator++() {
362 Usd_PrimDataSiblingIterator operator++(
int) {
363 Usd_PrimDataSiblingIterator result = *
this;
368 bool operator==(
const Usd_PrimDataSiblingIterator& other)
const {
369 return _underlyingIterator == other._underlyingIterator;
372 bool operator!=(
const Usd_PrimDataSiblingIterator& other)
const {
373 return _underlyingIterator != other._underlyingIterator;
377 friend class Usd_PrimData;
380 Usd_PrimDataSiblingIterator(
const _UnderylingIterator &i)
381 : _underlyingIterator(i) {}
384 _underlyingIterator = _underlyingIterator->GetNextSibling();
387 _UnderylingIterator _underlyingIterator =
nullptr;
390Usd_PrimDataSiblingIterator
391Usd_PrimData::_ChildrenBegin()
const
393 return Usd_PrimDataSiblingIterator(_firstChild);
396Usd_PrimDataSiblingIterator
397Usd_PrimData::_ChildrenEnd()
const
399 return Usd_PrimDataSiblingIterator(0);
403class Usd_PrimDataSubtreeIterator {
404 using _UnderlyingIterator = Usd_PrimData*;
406 using iterator_category = std::forward_iterator_tag;
407 using value_type = Usd_PrimData*;
408 using reference = Usd_PrimData*;
409 using pointer = void;
410 using difference_type = std::ptrdiff_t;
413 Usd_PrimDataSubtreeIterator() =
default;
415 reference operator*()
const {
return _underlyingIterator; }
418 Usd_PrimDataSubtreeIterator& operator++() {
424 Usd_PrimDataSubtreeIterator operator++(
int) {
425 Usd_PrimDataSubtreeIterator result = *
this;
430 bool operator==(
const Usd_PrimDataSubtreeIterator& other)
const {
431 return _underlyingIterator == other._underlyingIterator;
434 bool operator!=(
const Usd_PrimDataSubtreeIterator& other)
const {
435 return _underlyingIterator != other._underlyingIterator;
439 friend class Usd_PrimData;
443 Usd_PrimDataSubtreeIterator(
const _UnderlyingIterator &i)
444 : _underlyingIterator(i) {}
447 _underlyingIterator = _underlyingIterator->GetFirstChild() ?
448 _underlyingIterator->GetFirstChild() :
449 _underlyingIterator->GetNextPrim();
452 _UnderlyingIterator _underlyingIterator =
nullptr;
455Usd_PrimDataSubtreeIterator
456Usd_PrimData::_SubtreeBegin()
const
458 return Usd_PrimDataSubtreeIterator(
459 _firstChild ? _firstChild : GetNextPrim());
462Usd_PrimDataSubtreeIterator
463Usd_PrimData::_SubtreeEnd()
const
465 return Usd_PrimDataSubtreeIterator(GetNextPrim());
472template <
class PrimDataPtr>
474Usd_IsInstanceProxy(
const PrimDataPtr &p,
const SdfPath &proxyPrimPath)
476 return !proxyPrimPath.
IsEmpty();
486template <
class PrimDataPtr>
487inline Usd_PrimFlagsPredicate
488Usd_CreatePredicateForTraversal(
const PrimDataPtr &p,
490 Usd_PrimFlagsPredicate pred)
495 if (!Usd_IsInstanceProxy(p, proxyPrimPath) &&
496 !pred.IncludeInstanceProxiesInTraversal()) {
497 pred.TraverseInstanceProxies(
false);
506template <
class PrimDataPtr>
508Usd_MoveToParent(PrimDataPtr &p,
SdfPath &proxyPrimPath)
512 if (!proxyPrimPath.
IsEmpty()) {
515 if (p && p->IsPrototype()) {
516 p = p->GetPrimDataAtPathOrInPrototype(proxyPrimPath);
518 p->GetPath() == proxyPrimPath) {
536template <
class PrimDataPtr>
538Usd_MoveToNextSiblingOrParent(PrimDataPtr &p,
SdfPath &proxyPrimPath,
540 const Usd_PrimFlagsPredicate &pred)
544 const bool isInstanceProxy = Usd_IsInstanceProxy(p, proxyPrimPath);
546 PrimDataPtr next = p->GetNextSibling();
547 while (next && next != end &&
548 !Usd_EvalPredicate(pred, next, isInstanceProxy)) {
550 next = p->GetNextSibling();
552 p = next ? next : p->GetParentLink();
554 if (!proxyPrimPath.
IsEmpty()) {
558 else if (p == next) {
564 if (p && p->IsPrototype()) {
565 p = p->GetPrimDataAtPathOrInPrototype(proxyPrimPath);
567 p->GetPath() == proxyPrimPath) {
579template <
class PrimDataPtr>
581Usd_MoveToNextSiblingOrParent(PrimDataPtr &p,
SdfPath &proxyPrimPath,
582 const Usd_PrimFlagsPredicate &pred)
584 return Usd_MoveToNextSiblingOrParent(p, proxyPrimPath,
585 PrimDataPtr(
nullptr), pred);
593template <
class PrimDataPtr>
595Usd_MoveToChild(PrimDataPtr &p,
SdfPath &proxyPrimPath,
597 const Usd_PrimFlagsPredicate &pred)
599 bool isInstanceProxy = Usd_IsInstanceProxy(p, proxyPrimPath);
602 if (src->IsInstance()) {
603 src = src->GetPrototype();
604 isInstanceProxy =
true;
607 if (PrimDataPtr child = src->GetFirstChild()) {
608 if (isInstanceProxy) {
609 proxyPrimPath = proxyPrimPath.
IsEmpty() ?
610 p->GetPath().AppendChild(child->GetName()) :
616 if (Usd_EvalPredicate(pred, p, isInstanceProxy) ||
617 !Usd_MoveToNextSiblingOrParent(p, proxyPrimPath, end, pred)) {
625template <
class PrimDataPtr>
627Usd_MoveToChild(PrimDataPtr &p,
SdfPath &proxyPrimPath,
628 const Usd_PrimFlagsPredicate &pred)
630 return Usd_MoveToChild(p, proxyPrimPath, PrimDataPtr(
nullptr), pred);
633PXR_NAMESPACE_CLOSE_SCOPE
PcpPrimIndex is an index of the all sites of scene description that contribute opinions to a specific...
A path value used to locate objects in layers or scenegraphs.
SDF_API SdfPath GetParentPath() const
Return the path that identifies this path's namespace parent.
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 SdfPath AppendChild(TfToken const &childName) const
Creates a path by appending an element for childName to this path.
This class stores a T * and a small integer in the space of a T *.
Token for efficient comparison, assignment, and hashing of known strings.
Class representing the builtin definition of a prim given the schemas registered in the schema regist...
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Forward traversal iterator of sibling UsdPrim s.
Class that holds the full type information for a prim.
The outermost container for scene description, which owns and presents composed prims as a scenegraph...
Standard pointer typedefs.
#define TF_DECLARE_WEAK_PTRS(type)
Define standard weak pointer types.
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
std::vector< TfToken > TfTokenVector
Convenience types.
SdfSpecifier
An enum that identifies the possible specifiers for an SdfPrimSpec.