24#ifndef PXR_USD_USD_PRIM_DATA_H
25#define PXR_USD_USD_PRIM_DATA_H
30#include "pxr/usd/usd/api.h"
33#include "pxr/usd/usd/primDefinition.h"
34#include "pxr/usd/usd/primTypeInfo.h"
38#include "pxr/base/tf/pointerAndBits.h"
41#include "pxr/usd/sdf/path.h"
43#include <boost/intrusive_ptr.hpp>
49PXR_NAMESPACE_OPEN_SCOPE
86 const SdfPath &GetPath()
const {
return _path; }
88 const TfToken &GetName()
const {
return GetPath().GetNameToken(); }
90 UsdStage *GetStage()
const {
return _stage; }
94 return _primTypeInfo->GetPrimDefinition();
99 const TfToken& GetTypeName()
const {
100 return _primTypeInfo->GetTypeName();
105 return *_primTypeInfo;
109 bool IsPseudoRoot()
const {
return _flags[Usd_PrimPseudoRootFlag]; }
113 bool IsActive()
const {
return _flags[Usd_PrimActiveFlag]; }
118 bool IsLoaded()
const {
return _flags[Usd_PrimLoadedFlag]; }
122 bool IsModel()
const {
return _flags[Usd_PrimModelFlag]; }
127 bool IsGroup()
const {
return _flags[Usd_PrimGroupFlag]; }
129 bool IsComponent()
const {
return _flags[Usd_PrimComponentFlag]; }
132 bool IsSubComponent()
const;
135 bool IsAbstract()
const {
return _flags[Usd_PrimAbstractFlag]; }
139 bool IsDefined()
const {
return _flags[Usd_PrimDefinedFlag]; }
143 bool HasDefiningSpecifier()
const {
144 return _flags[Usd_PrimHasDefiningSpecifierFlag];
148 bool HasPayload()
const {
return _flags[Usd_PrimHasPayloadFlag]; }
153 bool MayHaveOpinionsInClips()
const {
return _flags[Usd_PrimClipsFlag]; }
165 Usd_PrimDataConstPtr GetParent()
const;
204 Usd_PrimDataPtr GetFirstChild()
const {
return _firstChild; }
207 Usd_PrimDataPtr GetNextSibling()
const {
208 return !_nextSiblingOrParent.BitsAs<
bool>() ?
209 _nextSiblingOrParent.Get() :
nullptr;
215 Usd_PrimDataPtr GetParentLink()
const {
216 return _nextSiblingOrParent.BitsAs<
bool>() ?
217 _nextSiblingOrParent.Get() :
nullptr;
223 inline Usd_PrimDataPtr GetNextPrim()
const {
224 if (Usd_PrimDataPtr sibling = GetNextSibling())
226 for (Usd_PrimDataPtr p = GetParentLink(); p; p = p->GetParentLink()) {
227 if (Usd_PrimDataPtr sibling = p->GetNextSibling())
236 USD_API Usd_PrimDataConstPtr
237 GetPrimDataAtPathOrInPrototype(
const SdfPath &path)
const;
245 bool IsInstance()
const {
return _flags[Usd_PrimInstanceFlag]; }
248 bool IsPrototype()
const {
249 return IsInPrototype() && GetPath().IsRootPrimPath();
254 bool IsInPrototype()
const {
return _flags[Usd_PrimPrototypeFlag]; }
258 USD_API Usd_PrimDataConstPtr GetPrototype()
const;
271 void _ComposeAndCacheFlags(
272 Usd_PrimDataConstPtr parent,
bool isPrototypePrim);
275 friend class Usd_PrimFlagsPredicate;
276 const Usd_PrimFlagBits &_GetFlags()
const {
288 void _SetSiblingLink(Usd_PrimDataPtr sibling) {
289 _nextSiblingOrParent.Set(sibling,
false);
292 void _SetParentLink(Usd_PrimDataPtr parent) {
293 _nextSiblingOrParent.Set(parent,
true);
298 _flags[Usd_PrimDeadFlag] =
true;
300 _primIndex =
nullptr;
304 bool _IsDead()
const {
return _flags[Usd_PrimDeadFlag]; }
308 void _SetMayHaveOpinionsInClips(
bool hasClips) {
309 _flags[Usd_PrimClipsFlag] = hasClips;
312 inline class Usd_PrimDataSiblingIterator _ChildrenBegin() const;
313 inline class Usd_PrimDataSiblingIterator _ChildrenEnd() const;
315 inline class Usd_PrimDataSubtreeIterator _SubtreeBegin() const;
316 inline class Usd_PrimDataSubtreeIterator _SubtreeEnd() const;
323 Usd_PrimData *_firstChild;
325 mutable std::atomic<int64_t> _refCount;
326 Usd_PrimFlagBits _flags;
329 friend void intrusive_ptr_add_ref(
const Usd_PrimData *prim) {
330 prim->_refCount.fetch_add(1, std::memory_order_relaxed);
332 friend void intrusive_ptr_release(
const Usd_PrimData *prim) {
333 if (prim->_refCount.fetch_sub(1, std::memory_order_release) == 1)
338 friend void Usd_ThrowExpiredPrimAccessError(Usd_PrimData
const *p);
340 Usd_DescribePrimData(
const Usd_PrimData *p,
SdfPath const &proxyPrimPath);
342 friend inline bool Usd_IsDead(Usd_PrimData
const *p) {
351class Usd_PrimDataSiblingIterator {
352 using _UnderylingIterator = Usd_PrimData*;
354 using iterator_category = std::forward_iterator_tag;
355 using value_type = Usd_PrimData*;
356 using reference = Usd_PrimData*;
357 using pointer = void;
358 using difference_type = std::ptrdiff_t;
361 Usd_PrimDataSiblingIterator() =
default;
363 reference operator*()
const {
return _underlyingIterator; }
366 Usd_PrimDataSiblingIterator& operator++() {
372 Usd_PrimDataSiblingIterator operator++(
int) {
373 Usd_PrimDataSiblingIterator result = *
this;
378 bool operator==(
const Usd_PrimDataSiblingIterator& other)
const {
379 return _underlyingIterator == other._underlyingIterator;
382 bool operator!=(
const Usd_PrimDataSiblingIterator& other)
const {
383 return _underlyingIterator != other._underlyingIterator;
387 friend class Usd_PrimData;
390 Usd_PrimDataSiblingIterator(
const _UnderylingIterator &i)
391 : _underlyingIterator(i) {}
394 _underlyingIterator = _underlyingIterator->GetNextSibling();
397 _UnderylingIterator _underlyingIterator =
nullptr;
400Usd_PrimDataSiblingIterator
401Usd_PrimData::_ChildrenBegin()
const
403 return Usd_PrimDataSiblingIterator(_firstChild);
406Usd_PrimDataSiblingIterator
407Usd_PrimData::_ChildrenEnd()
const
409 return Usd_PrimDataSiblingIterator(0);
413class Usd_PrimDataSubtreeIterator {
414 using _UnderlyingIterator = Usd_PrimData*;
416 using iterator_category = std::forward_iterator_tag;
417 using value_type = Usd_PrimData*;
418 using reference = Usd_PrimData*;
419 using pointer = void;
420 using difference_type = std::ptrdiff_t;
423 Usd_PrimDataSubtreeIterator() =
default;
425 reference operator*()
const {
return _underlyingIterator; }
428 Usd_PrimDataSubtreeIterator& operator++() {
434 Usd_PrimDataSubtreeIterator operator++(
int) {
435 Usd_PrimDataSubtreeIterator result = *
this;
440 bool operator==(
const Usd_PrimDataSubtreeIterator& other)
const {
441 return _underlyingIterator == other._underlyingIterator;
444 bool operator!=(
const Usd_PrimDataSubtreeIterator& other)
const {
445 return _underlyingIterator != other._underlyingIterator;
449 friend class Usd_PrimData;
453 Usd_PrimDataSubtreeIterator(
const _UnderlyingIterator &i)
454 : _underlyingIterator(i) {}
457 _underlyingIterator = _underlyingIterator->GetFirstChild() ?
458 _underlyingIterator->GetFirstChild() :
459 _underlyingIterator->GetNextPrim();
462 _UnderlyingIterator _underlyingIterator =
nullptr;
465Usd_PrimDataSubtreeIterator
466Usd_PrimData::_SubtreeBegin()
const
468 return Usd_PrimDataSubtreeIterator(
469 _firstChild ? _firstChild : GetNextPrim());
472Usd_PrimDataSubtreeIterator
473Usd_PrimData::_SubtreeEnd()
const
475 return Usd_PrimDataSubtreeIterator(GetNextPrim());
482template <
class PrimDataPtr>
484Usd_IsInstanceProxy(
const PrimDataPtr &p,
const SdfPath &proxyPrimPath)
486 return !proxyPrimPath.
IsEmpty();
496template <
class PrimDataPtr>
497inline Usd_PrimFlagsPredicate
498Usd_CreatePredicateForTraversal(
const PrimDataPtr &p,
500 Usd_PrimFlagsPredicate pred)
505 if (!Usd_IsInstanceProxy(p, proxyPrimPath) &&
506 !pred.IncludeInstanceProxiesInTraversal()) {
507 pred.TraverseInstanceProxies(
false);
516template <
class PrimDataPtr>
518Usd_MoveToParent(PrimDataPtr &p,
SdfPath &proxyPrimPath)
522 if (!proxyPrimPath.
IsEmpty()) {
525 if (p && p->IsPrototype()) {
526 p = p->GetPrimDataAtPathOrInPrototype(proxyPrimPath);
528 p->GetPath() == proxyPrimPath) {
546template <
class PrimDataPtr>
548Usd_MoveToNextSiblingOrParent(PrimDataPtr &p,
SdfPath &proxyPrimPath,
550 const Usd_PrimFlagsPredicate &pred)
554 const bool isInstanceProxy = Usd_IsInstanceProxy(p, proxyPrimPath);
556 PrimDataPtr next = p->GetNextSibling();
557 while (next && next != end &&
558 !Usd_EvalPredicate(pred, next, isInstanceProxy)) {
560 next = p->GetNextSibling();
562 p = next ? next : p->GetParentLink();
564 if (!proxyPrimPath.
IsEmpty()) {
568 else if (p == next) {
574 if (p && p->IsPrototype()) {
575 p = p->GetPrimDataAtPathOrInPrototype(proxyPrimPath);
577 p->GetPath() == proxyPrimPath) {
589template <
class PrimDataPtr>
591Usd_MoveToNextSiblingOrParent(PrimDataPtr &p,
SdfPath &proxyPrimPath,
592 const Usd_PrimFlagsPredicate &pred)
594 return Usd_MoveToNextSiblingOrParent(p, proxyPrimPath,
595 PrimDataPtr(
nullptr), pred);
603template <
class PrimDataPtr>
605Usd_MoveToChild(PrimDataPtr &p,
SdfPath &proxyPrimPath,
607 const Usd_PrimFlagsPredicate &pred)
609 bool isInstanceProxy = Usd_IsInstanceProxy(p, proxyPrimPath);
612 if (src->IsInstance()) {
613 src = src->GetPrototype();
614 isInstanceProxy =
true;
617 if (PrimDataPtr child = src->GetFirstChild()) {
618 if (isInstanceProxy) {
619 proxyPrimPath = proxyPrimPath.
IsEmpty() ?
620 p->GetPath().AppendChild(child->GetName()) :
626 if (Usd_EvalPredicate(pred, p, isInstanceProxy) ||
627 !Usd_MoveToNextSiblingOrParent(p, proxyPrimPath, end, pred)) {
635template <
class PrimDataPtr>
637Usd_MoveToChild(PrimDataPtr &p,
SdfPath &proxyPrimPath,
638 const Usd_PrimFlagsPredicate &pred)
640 return Usd_MoveToChild(p, proxyPrimPath, PrimDataPtr(
nullptr), pred);
643PXR_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.