All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
primRange.h
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_USD_USD_PRIM_RANGE_H
8#define PXR_USD_USD_PRIM_RANGE_H
9
10#include "pxr/pxr.h"
11#include "pxr/usd/usd/api.h"
12#include "pxr/usd/usd/common.h"
13#include "pxr/usd/usd/prim.h"
15
16#include <vector>
17#include <iterator>
18
19PXR_NAMESPACE_OPEN_SCOPE
20
102{
103public:
104 class iterator;
105
111 private:
112 friend class UsdPrimRange;
113 explicit EndSentinel(UsdPrimRange const *range) : _range(range) {}
114 friend class UsdPrimRange::iterator;
115 UsdPrimRange const *_range;
116 };
117
123 class iterator {
124 using _UnderlyingIterator = Usd_PrimDataConstPtr;
125 class _PtrProxy {
126 public:
127 UsdPrim* operator->() { return &_prim; }
128 private:
129 friend class iterator;
130 explicit _PtrProxy(const UsdPrim& prim) : _prim(prim) {}
131 UsdPrim _prim;
132 };
133 public:
134 using iterator_category = std::forward_iterator_tag;
135 using value_type = UsdPrim;
136 using reference = UsdPrim;
137 using pointer = _PtrProxy;
138 using difference_type = std::ptrdiff_t;
139
140 iterator() = default;
141
144 : _underlyingIterator(e._range->_end)
145 , _range(e._range) {}
146
147 reference operator*() const { return dereference(); }
148 pointer operator->() const { return pointer(dereference()); }
149
150 iterator& operator++() {
151 increment();
152 return *this;
153 }
154
155 iterator operator++(int) {
156 iterator result = *this;
157 increment();
158 return result;
159 }
160
163 bool IsPostVisit() const { return _isPost; }
164
168 USD_API void PruneChildren();
169
171 inline bool operator==(iterator const &other) const {
172 return _range == other._range &&
173 _underlyingIterator == other._underlyingIterator &&
174 _proxyPrimPath == other._proxyPrimPath &&
175 _depth == other._depth &&
176 _pruneChildrenFlag == other._pruneChildrenFlag &&
177 _isPost == other._isPost;
178 }
179
181 inline bool operator==(EndSentinel const &other) const {
182 return _range == other._range &&
183 _underlyingIterator == _range->_end;
184 }
185
187 inline bool operator!=(iterator const &other) const {
188 return !(*this == other);
189 }
190
192 inline bool operator!=(EndSentinel const &other) const {
193 return !(*this == other);
194 }
195
196 private:
197 friend class UsdPrimRange;
198
199 iterator(UsdPrimRange const *range,
200 Usd_PrimDataConstPtr prim,
201 SdfPath proxyPrimPath,
202 unsigned int depth)
203 : _underlyingIterator(prim)
204 , _range(range)
205 , _proxyPrimPath(proxyPrimPath)
206 , _depth(depth) {}
207
208 USD_API void increment();
209
210 inline reference dereference() const {
211 return UsdPrim(_underlyingIterator, _proxyPrimPath);
212 }
213
214 _UnderlyingIterator _underlyingIterator = nullptr;
215 UsdPrimRange const *_range = nullptr;
216 SdfPath _proxyPrimPath;
217 unsigned int _depth = 0;
218
219 // True when the client has asked that the next increment skips the
220 // children of the current prim.
221 bool _pruneChildrenFlag = false;
222 // True when we're on the post-side of a prim. Unused if
223 // _range->_postOrder is false.
224 bool _isPost = false;
225 };
226
227 using const_iterator = iterator;
228
230 : _begin(nullptr)
231 , _end(nullptr)
232 , _initDepth(0)
233 , _postOrder(false) {}
234
238 explicit UsdPrimRange(const UsdPrim &start) {
239 Usd_PrimDataConstPtr p = get_pointer(start._Prim());
240 _Init(p, p ? p->GetNextPrim() : nullptr, start._ProxyPrimPath());
241 }
242
245 UsdPrimRange(const UsdPrim &start,
246 const Usd_PrimFlagsPredicate &predicate) {
247 Usd_PrimDataConstPtr p = get_pointer(start._Prim());
248 _Init(p, p ? p->GetNextPrim() : nullptr,
249 start._ProxyPrimPath(), predicate);
250 }
251
262 static UsdPrimRange
263 PreAndPostVisit(const UsdPrim &start) {
264 UsdPrimRange result(start);
265 result._postOrder = true;
266 return result;
267 }
268
278 static UsdPrimRange
280 const Usd_PrimFlagsPredicate &predicate) {
281 UsdPrimRange result(start, predicate);
282 result._postOrder = true;
283 return result;
284 }
285
289 static UsdPrimRange
290 AllPrims(const UsdPrim &start) {
292 }
293
303 static UsdPrimRange
306 }
307
311 USD_API
312 static UsdPrimRange
313 Stage(const UsdStagePtr &stage,
314 const Usd_PrimFlagsPredicate &predicate = UsdPrimDefaultPredicate);
315
317 iterator begin() const {
318 return iterator(this, _begin, _initProxyPrimPath, _initDepth);
319 }
322 return iterator(this, _begin, _initProxyPrimPath, _initDepth);
323 }
324
326 UsdPrim front() const { return *begin(); }
327
328 // XXX C++11 & 14 require that c/end() return the same type as c/begin() for
329 // range-based-for loops to work correctly. C++17 relaxes that requirement.
330 // Change the return type to EndSentinel once we are on C++17.
331
333 iterator end() const { return EndSentinel(this); }
335 const_iterator cend() const { return EndSentinel(this); }
336
340 set_begin(++begin());
341 }
342
346 void set_begin(iterator const &newBegin) {
347 TF_VERIFY(!newBegin.IsPostVisit());
348 _begin = newBegin._underlyingIterator;
349 _initProxyPrimPath = newBegin._proxyPrimPath;
350 _initDepth = newBegin._depth;
351 }
352
354 bool empty() const { return begin() == end(); }
355
357 explicit operator bool() const { return !empty(); }
358
360 bool operator==(UsdPrimRange const &other) const {
361 return this == &other ||
362 (_begin == other._begin &&
363 _end == other._end &&
364 _initProxyPrimPath == other._initProxyPrimPath &&
365 _predicate == other._predicate &&
366 _postOrder == other._postOrder &&
367 _initDepth == other._initDepth);
368 }
369
371 bool operator!=(UsdPrimRange const &other) const {
372 return !(*this == other);
373 }
374
375private:
376 UsdPrimRange(Usd_PrimDataConstPtr begin,
377 Usd_PrimDataConstPtr end,
378 const SdfPath& proxyPrimPath,
379 const Usd_PrimFlagsPredicate &predicate =
381 _Init(begin, end, proxyPrimPath, predicate);
382 }
383
385 // Helpers.
386 void _Init(const Usd_PrimData *first,
387 const Usd_PrimData *last,
388 const SdfPath &proxyPrimPath,
389 const Usd_PrimFlagsPredicate &predicate =
391 _begin = first;
392 _end = last;
393 _initProxyPrimPath = proxyPrimPath;
394 _predicate = _begin ?
395 Usd_CreatePredicateForTraversal(_begin, proxyPrimPath, predicate) :
396 predicate;
397 _postOrder = false;
398 _initDepth = 0;
399
400 // Advance to the first prim that passes the predicate.
401 iterator b = begin();
402 if (b._underlyingIterator != _end &&
403 !Usd_EvalPredicate(_predicate, b._underlyingIterator,
404 proxyPrimPath)) {
405 b._pruneChildrenFlag = true;
406 set_begin(++b);
407 }
408 }
409
411 // Data members.
412
413 // These members are fixed for the life of the range.
414 Usd_PrimDataConstPtr _begin;
415 Usd_PrimDataConstPtr _end;
416 SdfPath _initProxyPrimPath;
417 Usd_PrimFlagsPredicate _predicate;
418 unsigned int _initDepth;
419 bool _postOrder;
420};
421
422
423PXR_NAMESPACE_CLOSE_SCOPE
424
425#endif // PXR_USD_USD_PRIM_RANGE_H
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:274
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Definition: prim.h:117
This class lets us represent past-the-end without the full weight of an iterator.
Definition: primRange.h:110
A forward iterator into a UsdPrimRange.
Definition: primRange.h:123
bool IsPostVisit() const
Return true if the iterator points to a prim visited the second time (in post order) for a pre- and p...
Definition: primRange.h:163
USD_API void PruneChildren()
Behave as if the current prim has no children when next advanced.
bool operator!=(iterator const &other) const
Return true if this iterator is not equivalent to other.
Definition: primRange.h:187
bool operator==(EndSentinel const &other) const
Return true if this iterator is equivalent to other.
Definition: primRange.h:181
bool operator==(iterator const &other) const
Return true if this iterator is equivalent to other.
Definition: primRange.h:171
bool operator!=(EndSentinel const &other) const
Return true if this iterator is not equivalent to other.
Definition: primRange.h:192
iterator(EndSentinel e)
Allow implicit conversion from EndSentinel.
Definition: primRange.h:143
An forward-iterable range that traverses a subtree of prims rooted at a given prim in depth-first ord...
Definition: primRange.h:102
iterator begin() const
Return an iterator to the start of this range.
Definition: primRange.h:317
static UsdPrimRange AllPrims(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:290
static UsdPrimRange AllPrimsPreAndPostVisit(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:304
const_iterator cbegin() const
Return a const_iterator to the start of this range.
Definition: primRange.h:321
static UsdPrimRange PreAndPostVisit(const UsdPrim &start)
Create a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:263
UsdPrimRange(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:238
bool empty() const
Return true if this range contains no prims, false otherwise.
Definition: primRange.h:354
iterator end() const
Return the past-the-end iterator for this range.
Definition: primRange.h:333
void increment_begin()
Modify this range by advancing the beginning by one.
Definition: primRange.h:339
bool operator==(UsdPrimRange const &other) const
Return true if this range is equivalent to other.
Definition: primRange.h:360
static USD_API UsdPrimRange Stage(const UsdStagePtr &stage, const Usd_PrimFlagsPredicate &predicate=UsdPrimDefaultPredicate)
Create a PrimRange that traverses all the prims on stage, and visits those that pass the default pred...
const_iterator cend() const
Return the past-the-end const_iterator for this range.
Definition: primRange.h:335
UsdPrimRange(const UsdPrim &start, const Usd_PrimFlagsPredicate &predicate)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:245
UsdPrim front() const
Return the first element of this range. The range must not be empty().
Definition: primRange.h:326
static UsdPrimRange PreAndPostVisit(const UsdPrim &start, const Usd_PrimFlagsPredicate &predicate)
Create a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:279
bool operator!=(UsdPrimRange const &other) const
Return true if this range is not equivalent to other.
Definition: primRange.h:371
void set_begin(iterator const &newBegin)
Set the start of this range to newBegin.
Definition: primRange.h:346
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition: diagnostic.h:266
unspecified UsdPrimDefaultPredicate
The default predicate used for prim traversals in methods like UsdPrim::GetChildren,...
unspecified UsdPrimAllPrimsPredicate
Predicate that includes all prims.