Loading...
Searching...
No Matches
primRange.h
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the Apache License, Version 2.0 (the "Apache License")
5// with the following modification; you may not use this file except in
6// compliance with the Apache License and the following modification to it:
7// Section 6. Trademarks. is deleted and replaced with:
8//
9// 6. Trademarks. This License does not grant permission to use the trade
10// names, trademarks, service marks, or product names of the Licensor
11// and its affiliates, except as required to comply with Section 4(c) of
12// the License and to reproduce the content of the NOTICE file.
13//
14// You may obtain a copy of the Apache License at
15//
16// http://www.apache.org/licenses/LICENSE-2.0
17//
18// Unless required by applicable law or agreed to in writing, software
19// distributed under the Apache License with the above modification is
20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21// KIND, either express or implied. See the Apache License for the specific
22// language governing permissions and limitations under the Apache License.
23//
24#ifndef PXR_USD_USD_PRIM_RANGE_H
25#define PXR_USD_USD_PRIM_RANGE_H
26
27#include "pxr/pxr.h"
28#include "pxr/usd/usd/api.h"
29#include "pxr/usd/usd/common.h"
30#include "pxr/usd/usd/prim.h"
32
33#include <vector>
34#include <iterator>
35
36PXR_NAMESPACE_OPEN_SCOPE
37
119{
120public:
121 class iterator;
122
128 private:
129 friend class UsdPrimRange;
130 explicit EndSentinel(UsdPrimRange const *range) : _range(range) {}
131 friend class UsdPrimRange::iterator;
132 UsdPrimRange const *_range;
133 };
134
140 class iterator {
141 using _UnderlyingIterator = Usd_PrimDataConstPtr;
142 class _PtrProxy {
143 public:
144 UsdPrim* operator->() { return &_prim; }
145 private:
146 friend class iterator;
147 explicit _PtrProxy(const UsdPrim& prim) : _prim(prim) {}
148 UsdPrim _prim;
149 };
150 public:
151 using iterator_category = std::forward_iterator_tag;
152 using value_type = UsdPrim;
153 using reference = UsdPrim;
154 using pointer = _PtrProxy;
155 using difference_type = std::ptrdiff_t;
156
157 iterator() = default;
158
161 : _underlyingIterator(e._range->_end)
162 , _range(e._range) {}
163
164 reference operator*() const { return dereference(); }
165 pointer operator->() const { return pointer(dereference()); }
166
167 iterator& operator++() {
168 increment();
169 return *this;
170 }
171
172 iterator operator++(int) {
173 iterator result = *this;
174 increment();
175 return result;
176 }
177
180 bool IsPostVisit() const { return _isPost; }
181
185 USD_API void PruneChildren();
186
188 inline bool operator==(iterator const &other) const {
189 return _range == other._range &&
190 _underlyingIterator == other._underlyingIterator &&
191 _proxyPrimPath == other._proxyPrimPath &&
192 _depth == other._depth &&
193 _pruneChildrenFlag == other._pruneChildrenFlag &&
194 _isPost == other._isPost;
195 }
196
198 inline bool operator==(EndSentinel const &other) const {
199 return _range == other._range &&
200 _underlyingIterator == _range->_end;
201 }
202
204 inline bool operator!=(iterator const &other) const {
205 return !(*this == other);
206 }
207
209 inline bool operator!=(EndSentinel const &other) const {
210 return !(*this == other);
211 }
212
213 private:
214 friend class UsdPrimRange;
215
216 iterator(UsdPrimRange const *range,
217 Usd_PrimDataConstPtr prim,
218 SdfPath proxyPrimPath,
219 unsigned int depth)
220 : _underlyingIterator(prim)
221 , _range(range)
222 , _proxyPrimPath(proxyPrimPath)
223 , _depth(depth) {}
224
225 USD_API void increment();
226
227 inline reference dereference() const {
228 return UsdPrim(_underlyingIterator, _proxyPrimPath);
229 }
230
231 _UnderlyingIterator _underlyingIterator = nullptr;
232 UsdPrimRange const *_range = nullptr;
233 SdfPath _proxyPrimPath;
234 unsigned int _depth = 0;
235
236 // True when the client has asked that the next increment skips the
237 // children of the current prim.
238 bool _pruneChildrenFlag = false;
239 // True when we're on the post-side of a prim. Unused if
240 // _range->_postOrder is false.
241 bool _isPost = false;
242 };
243
244 using const_iterator = iterator;
245
247 : _begin(nullptr)
248 , _end(nullptr)
249 , _initDepth(0)
250 , _postOrder(false) {}
251
255 explicit UsdPrimRange(const UsdPrim &start) {
256 Usd_PrimDataConstPtr p = get_pointer(start._Prim());
257 _Init(p, p ? p->GetNextPrim() : nullptr, start._ProxyPrimPath());
258 }
259
262 UsdPrimRange(const UsdPrim &start,
263 const Usd_PrimFlagsPredicate &predicate) {
264 Usd_PrimDataConstPtr p = get_pointer(start._Prim());
265 _Init(p, p ? p->GetNextPrim() : nullptr,
266 start._ProxyPrimPath(), predicate);
267 }
268
279 static UsdPrimRange
280 PreAndPostVisit(const UsdPrim &start) {
281 UsdPrimRange result(start);
282 result._postOrder = true;
283 return result;
284 }
285
295 static UsdPrimRange
297 const Usd_PrimFlagsPredicate &predicate) {
298 UsdPrimRange result(start, predicate);
299 result._postOrder = true;
300 return result;
301 }
302
306 static UsdPrimRange
307 AllPrims(const UsdPrim &start) {
309 }
310
320 static UsdPrimRange
323 }
324
328 USD_API
329 static UsdPrimRange
330 Stage(const UsdStagePtr &stage,
331 const Usd_PrimFlagsPredicate &predicate = UsdPrimDefaultPredicate);
332
334 iterator begin() const {
335 return iterator(this, _begin, _initProxyPrimPath, _initDepth);
336 }
339 return iterator(this, _begin, _initProxyPrimPath, _initDepth);
340 }
341
343 UsdPrim front() const { return *begin(); }
344
345 // XXX C++11 & 14 require that c/end() return the same type as c/begin() for
346 // range-based-for loops to work correctly. C++17 relaxes that requirement.
347 // Change the return type to EndSentinel once we are on C++17.
348
350 iterator end() const { return EndSentinel(this); }
352 const_iterator cend() const { return EndSentinel(this); }
353
357 set_begin(++begin());
358 }
359
363 void set_begin(iterator const &newBegin) {
364 TF_VERIFY(!newBegin.IsPostVisit());
365 _begin = newBegin._underlyingIterator;
366 _initProxyPrimPath = newBegin._proxyPrimPath;
367 _initDepth = newBegin._depth;
368 }
369
371 bool empty() const { return begin() == end(); }
372
374 explicit operator bool() const { return !empty(); }
375
377 bool operator==(UsdPrimRange const &other) const {
378 return this == &other ||
379 (_begin == other._begin &&
380 _end == other._end &&
381 _initProxyPrimPath == other._initProxyPrimPath &&
382 _predicate == other._predicate &&
383 _postOrder == other._postOrder &&
384 _initDepth == other._initDepth);
385 }
386
388 bool operator!=(UsdPrimRange const &other) const {
389 return !(*this == other);
390 }
391
392private:
393 UsdPrimRange(Usd_PrimDataConstPtr begin,
394 Usd_PrimDataConstPtr end,
395 const SdfPath& proxyPrimPath,
396 const Usd_PrimFlagsPredicate &predicate =
398 _Init(begin, end, proxyPrimPath, predicate);
399 }
400
402 // Helpers.
403 void _Init(const Usd_PrimData *first,
404 const Usd_PrimData *last,
405 const SdfPath &proxyPrimPath,
406 const Usd_PrimFlagsPredicate &predicate =
408 _begin = first;
409 _end = last;
410 _initProxyPrimPath = proxyPrimPath;
411 _predicate = _begin ?
412 Usd_CreatePredicateForTraversal(_begin, proxyPrimPath, predicate) :
413 predicate;
414 _postOrder = false;
415 _initDepth = 0;
416
417 // Advance to the first prim that passes the predicate.
418 iterator b = begin();
419 if (b._underlyingIterator != _end &&
420 !Usd_EvalPredicate(_predicate, b._underlyingIterator,
421 proxyPrimPath)) {
422 b._pruneChildrenFlag = true;
423 set_begin(++b);
424 }
425 }
426
428 // Data members.
429
430 // These members are fixed for the life of the range.
431 Usd_PrimDataConstPtr _begin;
432 Usd_PrimDataConstPtr _end;
433 SdfPath _initProxyPrimPath;
434 Usd_PrimFlagsPredicate _predicate;
435 unsigned int _initDepth;
436 bool _postOrder;
437};
438
439
440PXR_NAMESPACE_CLOSE_SCOPE
441
442#endif // PXR_USD_USD_PRIM_RANGE_H
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Definition: prim.h:134
This class lets us represent past-the-end without the full weight of an iterator.
Definition: primRange.h:127
A forward iterator into a UsdPrimRange.
Definition: primRange.h:140
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:180
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:204
bool operator==(EndSentinel const &other) const
Return true if this iterator is equivalent to other.
Definition: primRange.h:198
bool operator==(iterator const &other) const
Return true if this iterator is equivalent to other.
Definition: primRange.h:188
bool operator!=(EndSentinel const &other) const
Return true if this iterator is not equivalent to other.
Definition: primRange.h:209
iterator(EndSentinel e)
Allow implicit conversion from EndSentinel.
Definition: primRange.h:160
An forward-iterable range that traverses a subtree of prims rooted at a given prim in depth-first ord...
Definition: primRange.h:119
iterator begin() const
Return an iterator to the start of this range.
Definition: primRange.h:334
static UsdPrimRange AllPrims(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:307
static UsdPrimRange AllPrimsPreAndPostVisit(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:321
const_iterator cbegin() const
Return a const_iterator to the start of this range.
Definition: primRange.h:338
static UsdPrimRange PreAndPostVisit(const UsdPrim &start)
Create a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:280
UsdPrimRange(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order,...
Definition: primRange.h:255
bool empty() const
Return true if this range contains no prims, false otherwise.
Definition: primRange.h:371
iterator end() const
Return the past-the-end iterator for this range.
Definition: primRange.h:350
void increment_begin()
Modify this range by advancing the beginning by one.
Definition: primRange.h:356
bool operator==(UsdPrimRange const &other) const
Return true if this range is equivalent to other.
Definition: primRange.h:377
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:352
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:262
UsdPrim front() const
Return the first element of this range. The range must not be empty().
Definition: primRange.h:343
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:296
bool operator!=(UsdPrimRange const &other) const
Return true if this range is not equivalent to other.
Definition: primRange.h:388
void set_begin(iterator const &newBegin)
Set the start of this range to newBegin.
Definition: primRange.h:363
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition: diagnostic.h:283
unspecified UsdPrimDefaultPredicate
The default predicate used for prim traversals in methods like UsdPrim::GetChildren,...
unspecified UsdPrimAllPrimsPredicate
Predicate that includes all prims.