24 #ifndef PXR_USD_SDF_PATH_H 25 #define PXR_USD_SDF_PATH_H 28 #include "pxr/usd/sdf/api.h" 29 #include "pxr/usd/sdf/pool.h" 30 #include "pxr/usd/sdf/tokens.h" 35 #include <boost/intrusive_ptr.hpp> 36 #include <boost/operators.hpp> 42 #include <type_traits> 46 PXR_NAMESPACE_OPEN_SCOPE
56 typedef boost::intrusive_ptr<const Sdf_PathNode> Sdf_PathNodeConstRefPtr;
58 void intrusive_ptr_add_ref(Sdf_PathNode
const *);
59 void intrusive_ptr_release(Sdf_PathNode
const *);
62 struct Sdf_PathPrimTag;
63 struct Sdf_PathPropTag;
66 static constexpr
size_t Sdf_SizeofPrimPathNode =
sizeof(
void *) * 3;
67 static constexpr
size_t Sdf_SizeofPropPathNode =
sizeof(
void *) * 3;
69 using Sdf_PathPrimPartPool = Sdf_Pool<
70 Sdf_PathPrimTag, Sdf_SizeofPrimPathNode, 8>;
72 using Sdf_PathPropPartPool = Sdf_Pool<
73 Sdf_PathPropTag, Sdf_SizeofPropPathNode, 8>;
75 using Sdf_PathPrimHandle = Sdf_PathPrimPartPool::Handle;
76 using Sdf_PathPropHandle = Sdf_PathPropPartPool::Handle;
79 template <
class Handle,
bool Counted,
class PathNode=Sdf_PathNode const>
80 struct Sdf_PathNodeHandleImpl {
82 typedef Sdf_PathNodeHandleImpl this_type;
85 static constexpr
bool IsCounted = Counted;
87 constexpr Sdf_PathNodeHandleImpl() noexcept {};
90 Sdf_PathNodeHandleImpl(Sdf_PathNode
const *p,
bool add_ref =
true)
91 : _poolHandle(Handle::GetHandle(reinterpret_cast<char const *>(p))) {
98 Sdf_PathNodeHandleImpl(Handle h,
bool add_ref =
true)
105 Sdf_PathNodeHandleImpl(Sdf_PathNodeHandleImpl
const &rhs) noexcept
106 : _poolHandle(rhs._poolHandle) {
112 ~Sdf_PathNodeHandleImpl() {
118 Sdf_PathNodeHandleImpl &
119 operator=(Sdf_PathNodeHandleImpl
const &rhs) {
120 if (Counted && *
this == rhs) {
123 this_type(rhs).swap(*
this);
127 Sdf_PathNodeHandleImpl(Sdf_PathNodeHandleImpl &&rhs) noexcept
128 : _poolHandle(rhs._poolHandle) {
129 rhs._poolHandle =
nullptr;
132 Sdf_PathNodeHandleImpl &
133 operator=(Sdf_PathNodeHandleImpl &&rhs) noexcept {
134 this_type(std::move(rhs)).swap(*
this);
138 Sdf_PathNodeHandleImpl &
139 operator=(Sdf_PathNode
const *rhs) noexcept {
140 this_type(rhs).swap(*
this);
144 void reset() noexcept {
145 _poolHandle = Handle {
nullptr };
149 get() const noexcept {
150 return reinterpret_cast<Sdf_PathNode *>(_poolHandle.GetPtr());
163 explicit operator bool() const noexcept {
164 return static_cast<bool>(_poolHandle);
167 void swap(Sdf_PathNodeHandleImpl &rhs) noexcept {
168 _poolHandle.swap(rhs._poolHandle);
171 inline bool operator==(Sdf_PathNodeHandleImpl
const &rhs)
const noexcept {
172 return _poolHandle == rhs._poolHandle;
174 inline bool operator!=(Sdf_PathNodeHandleImpl
const &rhs)
const noexcept {
175 return _poolHandle != rhs._poolHandle;
177 inline bool operator<(Sdf_PathNodeHandleImpl
const &rhs)
const noexcept {
178 return _poolHandle < rhs._poolHandle;
182 void _AddRef(Sdf_PathNode
const *p)
const {
184 intrusive_ptr_add_ref(p);
188 void _AddRef()
const {
192 void _DecRef()
const {
194 intrusive_ptr_release(get());
198 Handle _poolHandle {
nullptr };
201 using Sdf_PathPrimNodeHandle =
202 Sdf_PathNodeHandleImpl<Sdf_PathPrimHandle,
true>;
204 using Sdf_PathPropNodeHandle =
205 Sdf_PathNodeHandleImpl<Sdf_PathPropHandle,
false>;
209 typedef std::set<class SdfPath> SdfPathSet;
211 typedef std::vector<class SdfPath> SdfPathVector;
214 VT_TYPE_IS_CHEAP_TO_COPY(
class SdfPath);
290 class SdfPath : boost::totally_ordered<SdfPath>
311 memset(
this, 0,
sizeof(*
this));
330 SDF_API
explicit SdfPath(
const std::string &path);
393 return static_cast<bool>(_propPart);
459 SDF_API
const std::string &
GetString()
const;
471 SDF_API
const char *
GetText()
const;
491 SDF_API
void GetPrefixes(SdfPathVector *prefixes)
const;
510 SDF_API
const std::string &
GetName()
const;
681 const std::string &variant)
const;
745 bool fixTargetPaths=
true)
const;
767 std::pair<SdfPath, SdfPath>
769 bool stopAtRootPrim =
false)
const;
823 static std::string
JoinIdentifier(
const std::vector<std::string> &names);
836 const std::string &rhs);
866 static std::pair<std::string, bool>
868 const std::string &matchNamespace);
876 std::string *errMsg = 0);
886 return _AsInt() == rhs._AsInt();
894 if (_AsInt() == rhs._AsInt()) {
897 if (!_primPart || !rhs._primPart) {
898 return !_primPart && rhs._primPart;
901 return _LessThanInternal(*
this, rhs);
904 template <
class HashState>
905 friend void TfHashAppend(HashState &h,
SdfPath const &path) {
908 uint32_t primPart, propPart;
909 memcpy(&primPart, &path._primPart,
sizeof(primPart));
910 memcpy(&propPart, &path._propPart,
sizeof(propPart));
917 inline size_t operator()(
const SdfPath& path)
const {
922 inline size_t GetHash()
const {
923 return Hash()(*this);
928 struct FastLessThan {
929 inline bool operator()(
const SdfPath& a,
const SdfPath& b)
const {
930 return a._AsInt() < b._AsInt();
945 SDF_API
static SdfPathVector
966 explicit SdfPath(Sdf_PathPrimNodeHandle &&primNode)
967 : _primPart(std::move(primNode)) {}
969 SdfPath(Sdf_PathPrimNodeHandle &&primPart,
970 Sdf_PathPropNodeHandle &&propPart)
971 : _primPart(std::move(primPart))
972 , _propPart(std::move(propPart)) {}
975 SdfPath(Sdf_PathPrimNodeHandle
const &primPart,
976 Sdf_PathPropNodeHandle
const &propPart)
977 : _primPart(primPart)
978 , _propPart(propPart) {}
981 SdfPath(Sdf_PathNode
const *primPart,
982 Sdf_PathNode
const *propPart)
983 : _primPart(primPart)
984 , _propPart(propPart) {}
986 friend class Sdf_PathNode;
987 friend class Sdfext_PathAccess;
992 _ElementsToString(
bool absolute,
const std::vector<std::string> &elements);
995 SdfPath const &newPrefix)
const;
998 SdfPath const &newPrefix)
const;
1002 bool fixTargetPaths)
const;
1008 inline uint64_t _AsInt()
const {
1009 static_assert(
sizeof(*
this) ==
sizeof(uint64_t),
"");
1011 std::memcpy(&ret,
this,
sizeof(*
this));
1016 lhs._primPart.swap(rhs._primPart);
1017 lhs._propPart.swap(rhs._propPart);
1020 SDF_API
friend char const *
1021 Sdf_PathGetDebuggerPathText(
SdfPath const &);
1023 Sdf_PathPrimNodeHandle _primPart;
1024 Sdf_PathPropNodeHandle _propPart;
1052 const SdfPath& GetPath()
const {
return _path; }
1055 using iterator_category = std::forward_iterator_tag;
1057 using difference_type = std::ptrdiff_t;
1058 using reference =
const SdfPath&;
1059 using pointer =
const SdfPath*;
1061 iterator(
const SdfPath& path) : _path(path) {}
1063 iterator() =
default;
1066 iterator& operator++();
1068 const SdfPath& operator*()
const {
return _path; }
1070 const SdfPath* operator->()
const {
return &_path; }
1072 bool operator==(
const iterator& o)
const {
return _path == o._path; }
1074 bool operator!=(
const iterator& o)
const {
return _path != o._path; }
1079 SDF_API
friend difference_type
1080 distance(
const iterator& first,
const iterator& last);
1086 iterator begin()
const {
return iterator(_path); }
1088 iterator end()
const {
return iterator(); }
1096 inline size_t hash_value(
SdfPath const &path)
1098 return path.GetHash();
1106 struct Sdf_PathIdentity {
1118 template <
class ForwardIterator,
class GetPathFn = Sdf_PathIdentity>
1119 std::pair<ForwardIterator, ForwardIterator>
1120 SdfPathFindPrefixedRange(ForwardIterator begin, ForwardIterator end,
1122 GetPathFn
const &getPath = GetPathFn()) {
1124 typename std::iterator_traits<ForwardIterator>::reference;
1127 Compare(GetPathFn
const &getPath) : _getPath(getPath) {}
1128 GetPathFn
const &_getPath;
1129 bool operator()(IterRef a,
SdfPath const &b)
const {
1130 return _getPath(a) < b;
1134 std::pair<ForwardIterator, ForwardIterator> result;
1137 result.first = std::lower_bound(begin, end, prefix, Compare(getPath));
1141 result.second = TfFindBoundary(result.first, end,
1142 [&prefix, &getPath](IterRef iterRef) {
1143 return getPath(iterRef).HasPrefix(prefix);
1149 template <
class RandomAccessIterator,
class GetPathFn>
1150 RandomAccessIterator
1151 Sdf_PathFindLongestPrefixImpl(RandomAccessIterator begin,
1152 RandomAccessIterator end,
1155 GetPathFn
const &getPath)
1158 typename std::iterator_traits<RandomAccessIterator>::reference;
1161 Compare(GetPathFn
const &getPath) : _getPath(getPath) {}
1162 GetPathFn
const &_getPath;
1163 bool operator()(IterRef a,
SdfPath const &b)
const {
1164 return _getPath(a) < b;
1177 Compare comp(getPath);
1180 RandomAccessIterator result = std::lower_bound(begin, end, path, comp);
1184 if (!strictPrefix && result != end && getPath(*result) == path) {
1190 if (result == begin) {
1195 if (path.
HasPrefix(getPath(*--result))) {
1205 result = std::lower_bound(begin, end, newPath, comp);
1207 if (result != end && getPath(*result) == newPath) {
1210 if (result == begin) {
1213 if (newPath.
HasPrefix(getPath(*--result))) {
1227 template <
class RandomAccessIterator,
class GetPathFn = Sdf_PathIdentity,
1228 class =
typename std::enable_if<
1230 std::random_access_iterator_tag,
1231 typename std::iterator_traits<
1232 RandomAccessIterator>::iterator_category
1236 RandomAccessIterator
1237 SdfPathFindLongestPrefix(RandomAccessIterator begin,
1238 RandomAccessIterator end,
1240 GetPathFn
const &getPath = GetPathFn())
1242 return Sdf_PathFindLongestPrefixImpl(
1243 begin, end, path,
false, getPath);
1253 template <
class RandomAccessIterator,
class GetPathFn = Sdf_PathIdentity,
1254 class =
typename std::enable_if<
1256 std::random_access_iterator_tag,
1257 typename std::iterator_traits<
1258 RandomAccessIterator>::iterator_category
1262 RandomAccessIterator
1263 SdfPathFindLongestStrictPrefix(RandomAccessIterator begin,
1264 RandomAccessIterator end,
1266 GetPathFn
const &getPath = GetPathFn())
1268 return Sdf_PathFindLongestPrefixImpl(
1269 begin, end, path,
true, getPath);
1272 template <
class Iter,
class MapParam,
class GetPathFn = Sdf_PathIdentity>
1274 Sdf_PathFindLongestPrefixImpl(
1275 MapParam map,
SdfPath const &path,
bool strictPrefix,
1276 GetPathFn
const &getPath = GetPathFn())
1283 const Iter mapEnd = map.end();
1290 Iter result = map.lower_bound(path);
1294 if (!strictPrefix && result != mapEnd && getPath(*result) == path)
1299 if (result == map.begin())
1310 return Sdf_PathFindLongestPrefixImpl<Iter, MapParam>(
1319 typename std::set<SdfPath>::const_iterator
1320 SdfPathFindLongestPrefix(std::set<SdfPath>
const &set,
SdfPath const &path);
1326 typename std::map<SdfPath, T>::const_iterator
1327 SdfPathFindLongestPrefix(std::map<SdfPath, T>
const &map,
SdfPath const &path)
1329 return Sdf_PathFindLongestPrefixImpl<
1330 typename std::map<SdfPath, T>::const_iterator,
1331 std::map<SdfPath, T>
const &>(map, path,
false,
1335 typename std::map<SdfPath, T>::iterator
1336 SdfPathFindLongestPrefix(std::map<SdfPath, T> &map,
SdfPath const &path)
1338 return Sdf_PathFindLongestPrefixImpl<
1339 typename std::map<SdfPath, T>::iterator,
1340 std::map<SdfPath, T> &>(map, path,
false,
1348 typename std::set<SdfPath>::const_iterator
1349 SdfPathFindLongestStrictPrefix(std::set<SdfPath>
const &set,
1356 typename std::map<SdfPath, T>::const_iterator
1357 SdfPathFindLongestStrictPrefix(
1358 std::map<SdfPath, T>
const &map,
SdfPath const &path)
1360 return Sdf_PathFindLongestPrefixImpl<
1361 typename std::map<SdfPath, T>::const_iterator,
1362 std::map<SdfPath, T>
const &>(map, path,
true,
1366 typename std::map<SdfPath, T>::iterator
1367 SdfPathFindLongestStrictPrefix(
1368 std::map<SdfPath, T> &map,
SdfPath const &path)
1370 return Sdf_PathFindLongestPrefixImpl<
1371 typename std::map<SdfPath, T>::iterator,
1372 std::map<SdfPath, T> &>(map, path,
true,
1383 Sdf_PathGetDebuggerPathText(
SdfPath const &);
1385 PXR_NAMESPACE_CLOSE_SCOPE
1390 #include "pxr/usd/sdf/pathNode.h" 1392 PXR_NAMESPACE_OPEN_SCOPE
1394 static_assert(Sdf_SizeofPrimPathNode ==
sizeof(Sdf_PrimPathNode),
"");
1395 static_assert(Sdf_SizeofPropPathNode ==
sizeof(Sdf_PrimPropertyPathNode),
"");
1397 PXR_NAMESPACE_CLOSE_SCOPE
1399 #endif // PXR_USD_SDF_PATH_H SDF_API SdfPath AppendMapper(const SdfPath &targetPath) const
Creates a path by appending a mapper element for targetPath.
Range representing a path and ancestors, and providing methods for iterating over them.
static SDF_API std::string StripNamespace(const std::string &name)
Returns name stripped of any namespaces.
SDF_API bool IsMapperPath() const
Returns whether the path identifies a connection mapper.
SDF_API bool IsAbsoluteRootPath() const
Return true if this path is the AbsoluteRootPath().
SDF_API bool IsPrimPropertyPath() const
Returns whether the path identifies a prim's property.
SDF_API SdfPath AppendPath(const SdfPath &newSuffix) const
Creates a path by appending a given relative path to this path.
SDF_API SdfPathVector GetPrefixes() const
Returns the prefix paths of this path.
SDF_API bool IsPrimPath() const
Returns whether the path identifies a prim.
SDF_API SdfPath StripAllVariantSelections() const
Create a path by stripping all variant selections from all components of this path,...
SDF_API std::string GetElementString() const
Returns an ascii representation of the "terminal" element of this path, which can be used to reconstr...
SDF_API bool IsPrimVariantSelectionPath() const
Returns whether the path identifies a variant selection for a prim.
SDF_API TfToken const & GetToken() const
Return the string representation of this path as a TfToken lvalue.
bool operator==(const SdfPath &rhs) const
Equality operator.
static SDF_API bool IsValidNamespacedIdentifier(const std::string &name)
Returns whether name is a legal namespaced identifier.
SDF_API SdfPathAncestorsRange GetAncestorsRange() const
Return a range for iterating over the ancestors of this path.
SDF_API const char * GetText() const
Returns the string representation of this path as a c string.
SDF_API SdfPath ReplacePrefix(const SdfPath &oldPrefix, const SdfPath &newPrefix, bool fixTargetPaths=true) const
Returns a path with all occurrences of the prefix path oldPrefix replaced with the prefix path newPre...
static SDF_API TfTokenVector TokenizeIdentifierAsTokens(const std::string &name)
Tokenizes name by the namespace delimiter.
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.
SDF_API SdfPath GetPrimOrPrimVariantSelectionPath() const
Creates a path by stripping all relational attributes, targets, and properties, leaving the nearest p...
static SDF_API bool IsValidPathString(const std::string &pathString, std::string *errMsg=0)
Return true if pathString is a valid path string, meaning that passing the string to the SdfPath cons...
SDF_API TfToken GetAsToken() const
Return the string representation of this path as a TfToken.
static SDF_API void RemoveDescendentPaths(SdfPathVector *paths)
Remove all elements of paths that are prefixed by other elements in paths.
SDF_API SdfPath GetParentPath() const
Return the path that identifies this path's namespace parent.
A user-extensible hashing mechanism for use with runtime hash tables.
SDF_API bool IsRelationalAttributePath() const
Returns whether the path identifies a relational attribute.
Token for efficient comparison, assignment, and hashing of known strings.
static SDF_API SdfPathVector GetConciseRelativePaths(const SdfPathVector &paths)
Given some vector of paths, get a vector of concise unambiguous relative paths.
SDF_API bool IsNamespacedPropertyPath() const
Returns whether the path identifies a namespaced property.
SDF_API const std::string & GetName() const
Returns the name of the prim, property or relational attribute identified by the path.
bool operator<(const SdfPath &rhs) const
Comparison operator.
SDF_API bool IsAbsoluteRootOrPrimPath() const
Returns whether the path identifies a prim or the absolute root.
SDF_API SdfPath AppendElementString(const std::string &element) const
Creates a path by extracting and appending an element from the given ascii element encoding.
SDF_API bool IsExpressionPath() const
Returns whether the path identifies a connection expression.
SDF_API SdfPath MakeRelativePath(const SdfPath &anchor) const
Returns the relative form of this path using anchor as the relative basis.
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.
SDF_API SdfPath ReplaceTargetPath(const SdfPath &newTargetPath) const
Replaces the relational attribute's target path.
SDF_API SdfPath MakeAbsolutePath(const SdfPath &anchor) const
Returns the absolute form of this path using anchor as the relative basis.
SDF_API bool IsPrimOrPrimVariantSelectionPath() const
Return true if this path is a prim path or is a prim variant selection path.
SDF_API void GetAllTargetPathsRecursively(SdfPathVector *result) const
Returns all the relationship target or connection target paths contained in this path,...
SDF_API size_t GetPathElementCount() const
Returns the number of path elements in this path.
static SDF_API const SdfPath & ReflexiveRelativePath()
The relative path representing "self".
SDF_API std::string GetAsString() const
Return the string representation of this path as a std::string.
SdfPath() noexcept
Constructs the default, empty path.
std::vector< TfToken > TfTokenVector
Convenience types.
SDF_API const TfToken & GetNameToken() const
Returns the name of the prim, property or relational attribute identified by the path,...
Function object for retrieving the N'th element of a std::pair or std::tuple.
A path value used to locate objects in layers or scenegraphs.
SDF_API SdfPath GetCommonPrefix(const SdfPath &path) const
Returns a path with maximal length that is a prefix path of both this path and path.
SDF_API const std::string & GetString() const
Return the string representation of this path as a std::string.
SDF_API bool IsAbsolutePath() const
Returns whether the path is absolute.
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
SDF_API SdfPath GetPrimPath() const
Creates a path by stripping all relational attributes, targets, properties, and variant selections fr...
static SDF_API std::string JoinIdentifier(const std::vector< std::string > &names)
Join names into a single identifier using the namespace delimiter.
SDF_API SdfPath AppendTarget(const SdfPath &targetPath) const
Creates a path by appending an element for targetPath.
SDF_API bool IsMapperArgPath() const
Returns whether the path identifies a connection mapper arg.
SDF_API SdfPath AppendMapperArg(TfToken const &argName) const
Creates a path by appending an element for argName.
SDF_API SdfPath ReplaceName(TfToken const &newName) const
Return a copy of this path with its final component changed to newName.
static SDF_API const SdfPath & AbsoluteRootPath()
The absolute path representing the top of the namespace hierarchy.
static SDF_API std::pair< std::string, bool > StripPrefixNamespace(const std::string &name, const std::string &matchNamespace)
Returns (name, true) where name is stripped of the prefix specified by matchNamespace if name indeed ...
SDF_API SdfPath AppendExpression() const
Creates a path by appending an expression element.
SDF_API SdfPath AppendProperty(TfToken const &propName) const
Creates a path by appending an element for propName to this path.
SDF_API bool ContainsTargetPath() const
Return true if this path is or has a prefix that's a target path or a mapper path.
SDF_API SdfPath AppendRelationalAttribute(TfToken const &attrName) const
Creates a path by appending an element for attrName to this path.
SDF_API TfToken GetElementToken() const
Like GetElementString() but return the value as a TfToken.
SDF_API bool IsRootPrimPath() const
Returns whether the path identifies a root prim.
SDF_API SdfPath AppendElementToken(const TfToken &elementTok) const
Like AppendElementString() but take the element as a TfToken.
SDF_API bool IsPropertyPath() const
Returns whether the path identifies a property.
SDF_API SdfPath AppendVariantSelection(const std::string &variantSet, const std::string &variant) const
Creates a path by appending an element for variantSet and variant to this path.
SDF_API std::pair< SdfPath, SdfPath > RemoveCommonSuffix(const SdfPath &otherPath, bool stopAtRootPrim=false) const
Find and remove the longest common suffix from two paths.
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.
static SDF_API std::vector< std::string > TokenizeIdentifier(const std::string &name)
Tokenizes name by the namespace delimiter.
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
SDF_API const SdfPath & GetTargetPath() const
Returns the relational attribute or mapper target path for this path.
static SDF_API const SdfPath & EmptyPath()
The empty path value, equivalent to SdfPath().
SDF_API bool ContainsPrimVariantSelection() const
Returns whether the path or any of its parent paths identifies a variant selection for a prim.
SDF_API std::pair< std::string, std::string > GetVariantSelection() const
Returns the variant selection for this path, if this is a variant selection path.
SDF_API SdfPath AppendChild(TfToken const &childName) const
Creates a path by appending an element for childName to this path.
static SDF_API void RemoveAncestorPaths(SdfPathVector *paths)
Remove all elements of paths that prefix other elements in paths.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
static SDF_API bool IsValidIdentifier(const std::string &name)
Returns whether name is a legal identifier for any path component.
SDF_API bool IsTargetPath() const
Returns whether the path identifies a relationship or connection target.
SDF_API SdfPath GetAbsoluteRootOrPrimPath() const
Creates a path by stripping all properties and relational attributes from this path,...
bool ContainsPropertyElements() const
Return true if this path contains any property elements, false otherwise.