All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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"
31 #include "pxr/usd/usd/primFlags.h"
32 
33 #include <vector>
34 #include <iterator>
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
119 {
120 public:
121  class iterator;
122 
127  class EndSentinel {
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 : public boost::iterator_adaptor<
141  iterator, // crtp base.
142  Usd_PrimDataConstPtr, // base iterator.
143  UsdPrim, // value type.
144  boost::forward_traversal_tag, // traversal.
145  UsdPrim> // reference type.
146  {
147  public:
148  iterator() : iterator_adaptor_(nullptr) {}
149 
152  : iterator_adaptor_(e._range->_end)
153  , _range(e._range) {}
154 
157  bool IsPostVisit() const { return _isPost; }
158 
162  USD_API void PruneChildren();
163 
165  inline bool operator==(iterator const &other) const {
166  return _range == other._range &&
167  base() == other.base() &&
168  _proxyPrimPath == other._proxyPrimPath &&
169  _depth == other._depth &&
170  _pruneChildrenFlag == other._pruneChildrenFlag &&
171  _isPost == other._isPost;
172  }
173 
175  inline bool operator==(EndSentinel const &other) const {
176  return _range == other._range && base() == _range->_end;
177  }
178 
180  inline bool operator!=(iterator const &other) const {
181  return !(*this == other);
182  }
183 
185  inline bool operator!=(EndSentinel const &other) const {
186  return !(*this == other);
187  }
188 
189  private:
190  friend class UsdPrimRange;
191  friend class boost::iterator_core_access;
192 
193  iterator(UsdPrimRange const *range,
194  Usd_PrimDataConstPtr prim,
195  SdfPath proxyPrimPath,
196  unsigned int depth)
197  : iterator_adaptor_(prim)
198  , _range(range)
199  , _proxyPrimPath(proxyPrimPath)
200  , _depth(depth) {}
201 
202  USD_API void increment();
203 
204  inline reference dereference() const {
205  return UsdPrim(base(), _proxyPrimPath);
206  }
207 
208  UsdPrimRange const *_range = nullptr;
209  SdfPath _proxyPrimPath;
210  unsigned int _depth = 0;
211 
212  // True when the client has asked that the next increment skips the
213  // children of the current prim.
214  bool _pruneChildrenFlag = false;
215  // True when we're on the post-side of a prim. Unused if
216  // _range->_postOrder is false.
217  bool _isPost = false;
218  };
219 
220  using const_iterator = iterator;
221 
222  UsdPrimRange()
223  : _begin(nullptr)
224  , _end(nullptr)
225  , _initDepth(0)
226  , _postOrder(false) {}
227 
231  explicit UsdPrimRange(const UsdPrim &start) {
232  Usd_PrimDataConstPtr p = get_pointer(start._Prim());
233  _Init(p, p ? p->GetNextPrim() : nullptr, start._ProxyPrimPath());
234  }
235 
238  UsdPrimRange(const UsdPrim &start,
239  const Usd_PrimFlagsPredicate &predicate) {
240  Usd_PrimDataConstPtr p = get_pointer(start._Prim());
241  _Init(p, p ? p->GetNextPrim() : nullptr,
242  start._ProxyPrimPath(), predicate);
243  }
244 
255  static UsdPrimRange
256  PreAndPostVisit(const UsdPrim &start) {
257  UsdPrimRange result(start);
258  result._postOrder = true;
259  return result;
260  }
261 
271  static UsdPrimRange
272  PreAndPostVisit(const UsdPrim &start,
273  const Usd_PrimFlagsPredicate &predicate) {
274  UsdPrimRange result(start, predicate);
275  result._postOrder = true;
276  return result;
277  }
278 
282  static UsdPrimRange
283  AllPrims(const UsdPrim &start) {
284  return UsdPrimRange(start, UsdPrimAllPrimsPredicate);
285  }
286 
296  static UsdPrimRange
299  }
300 
304  USD_API
305  static UsdPrimRange
306  Stage(const UsdStagePtr &stage,
307  const Usd_PrimFlagsPredicate &predicate = UsdPrimDefaultPredicate);
308 
310  iterator begin() const {
311  return iterator(this, _begin, _initProxyPrimPath, _initDepth);
312  }
315  return iterator(this, _begin, _initProxyPrimPath, _initDepth);
316  }
317 
319  UsdPrim front() const { return *begin(); }
320 
321  // XXX C++11 & 14 require that c/end() return the same type as c/begin() for
322  // range-based-for loops to work correctly. C++17 relaxes that requirement.
323  // Change the return type to EndSentinel once we are on C++17.
324 
326  iterator end() const { return EndSentinel(this); }
328  const_iterator cend() const { return EndSentinel(this); }
329 
333  set_begin(++begin());
334  }
335 
339  void set_begin(iterator const &newBegin) {
340  TF_VERIFY(!newBegin.IsPostVisit());
341  _begin = newBegin.base();
342  _initProxyPrimPath = newBegin._proxyPrimPath;
343  _initDepth = newBegin._depth;
344  }
345 
347  bool empty() const { return begin() == end(); }
348 
350  explicit operator bool() const { return !empty(); }
351 
353  bool operator==(UsdPrimRange const &other) const {
354  return this == &other ||
355  (_begin == other._begin &&
356  _end == other._end &&
357  _initProxyPrimPath == other._initProxyPrimPath &&
358  _predicate == other._predicate &&
359  _postOrder == other._postOrder &&
360  _initDepth == other._initDepth);
361  }
362 
364  bool operator!=(UsdPrimRange const &other) const {
365  return !(*this == other);
366  }
367 
368 private:
369  UsdPrimRange(Usd_PrimDataConstPtr begin,
370  Usd_PrimDataConstPtr end,
371  const SdfPath& proxyPrimPath,
372  const Usd_PrimFlagsPredicate &predicate =
374  _Init(begin, end, proxyPrimPath, predicate);
375  }
376 
378  // Helpers.
379  void _Init(const Usd_PrimData *first,
380  const Usd_PrimData *last,
381  const SdfPath &proxyPrimPath,
382  const Usd_PrimFlagsPredicate &predicate =
384  _begin = first;
385  _end = last;
386  _initProxyPrimPath = proxyPrimPath;
387  _predicate = _begin ?
388  Usd_CreatePredicateForTraversal(_begin, proxyPrimPath, predicate) :
389  predicate;
390  _postOrder = false;
391  _initDepth = 0;
392 
393  // Advance to the first prim that passes the predicate.
394  iterator b = begin();
395  if (b.base() != _end &&
396  !Usd_EvalPredicate(_predicate, b.base(), proxyPrimPath)) {
397  b._pruneChildrenFlag = true;
398  set_begin(++b);
399  }
400  }
401 
403  // Data members.
404 
405  // These members are fixed for the life of the range.
406  Usd_PrimDataConstPtr _begin;
407  Usd_PrimDataConstPtr _end;
408  SdfPath _initProxyPrimPath;
409  Usd_PrimFlagsPredicate _predicate;
410  unsigned int _initDepth;
411  bool _postOrder;
412 };
413 
414 
415 PXR_NAMESPACE_CLOSE_SCOPE
416 
417 #endif // PXR_USD_USD_PRIM_RANGE_H
iterator begin() const
Return an iterator to the start of this range.
Definition: primRange.h:310
unspecified UsdPrimDefaultPredicate
The default predicate used for prim traversals in methods like UsdPrim::GetChildren, UsdStage::Traverse, and by UsdPrimRange.
bool operator==(EndSentinel const &other) const
Return true if this iterator is equivalent to other.
Definition: primRange.h:175
This class lets us represent past-the-end without the full weight of an iterator. ...
Definition: primRange.h:127
static UsdPrimRange AllPrimsPreAndPostVisit(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order, visiting all prims (including deactivated, undefined, and abstract prims) with pre- and post-order visitation.
Definition: primRange.h:297
void set_begin(iterator const &newBegin)
Set the start of this range to newBegin.
Definition: primRange.h:339
UsdPrimRange(const UsdPrim &start, const Usd_PrimFlagsPredicate &predicate)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order, visiting prims that pass predicate.
Definition: primRange.h:238
bool operator!=(iterator const &other) const
Return true if this iterator is not equivalent to other.
Definition: primRange.h:180
static UsdPrimRange AllPrims(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order, visiting all prims (including deactivated, undefined, and abstract prims).
Definition: primRange.h:283
const_iterator cend() const
Return the past-the-end const_iterator for this range.
Definition: primRange.h:328
const_iterator cbegin() const
Return a const_iterator to the start of this range.
Definition: primRange.h:314
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition: diagnostic.h:283
bool operator==(UsdPrimRange const &other) const
Return true if this range is equivalent to other.
Definition: primRange.h:353
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a &quot;Prim&quot; as ...
Definition: prim.h:132
bool empty() const
Return true if this range contains no prims, false otherwise.
Definition: primRange.h:347
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:288
USD_API void PruneChildren()
Behave as if the current prim has no children when next advanced.
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...
UsdPrim front() const
Return the first element of this range. The range must not be empty().
Definition: primRange.h:319
UsdPrimRange(const UsdPrim &start)
Construct a PrimRange that traverses the subtree rooted at start in depth-first order, visiting prims that pass the default predicate (as defined by UsdPrimDefaultPredicate).
Definition: primRange.h:231
iterator(EndSentinel e)
Allow implicit conversion from EndSentinel.
Definition: primRange.h:151
An forward-iterable range that traverses a subtree of prims rooted at a given prim in depth-first ord...
Definition: primRange.h:118
void increment_begin()
Modify this range by advancing the beginning by one.
Definition: primRange.h:332
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:157
static UsdPrimRange PreAndPostVisit(const UsdPrim &start)
Create a PrimRange that traverses the subtree rooted at start in depth-first order, visiting prims that pass the default predicate (as defined by UsdPrimDefaultPredicate) with pre- and post-order visitation.
Definition: primRange.h:256
unspecified UsdPrimAllPrimsPredicate
Predicate that includes all prims.
iterator end() const
Return the past-the-end iterator for this range.
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, visiting prims that pass predicate with pre- and post-order visitation.
Definition: primRange.h:272
A forward iterator into a UsdPrimRange.
Definition: primRange.h:140
bool operator!=(EndSentinel const &other) const
Return true if this iterator is not equivalent to other.
Definition: primRange.h:185
bool operator==(iterator const &other) const
Return true if this iterator is equivalent to other.
Definition: primRange.h:165
bool operator!=(UsdPrimRange const &other) const
Return true if this range is not equivalent to other.
Definition: primRange.h:364