All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
timeCodeRange.h
Go to the documentation of this file.
1 //
2 // Copyright 2019 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 USDUTILS_TIME_CODE_RANGE_H
25 #define USDUTILS_TIME_CODE_RANGE_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usdUtils/api.h"
31 
32 #include "pxr/base/gf/math.h"
33 #include "pxr/base/tf/diagnostic.h"
34 #include "pxr/base/tf/staticTokens.h"
35 #include "pxr/usd/usd/timeCode.h"
36 
37 #include <iosfwd>
38 #include <iterator>
39 #include <string>
40 
41 
42 PXR_NAMESPACE_OPEN_SCOPE
43 
44 
45 #define USDUTILS_TIME_CODE_RANGE_TOKENS \
46  ((EmptyTimeCodeRange, "NONE")) \
47  ((RangeSeparator, ":")) \
48  ((StrideSeparator, "x"))
49 
51  UsdUtilsTimeCodeRangeTokens,
52  USDUTILS_API,
53  USDUTILS_TIME_CODE_RANGE_TOKENS);
54 
55 
74 {
75 public:
76 
81  {
82  public:
83  using iterator_category = std::forward_iterator_tag;
84  using value_type = UsdTimeCode;
85  using reference = const UsdTimeCode&;
86  using pointer = const UsdTimeCode*;
87  using difference_type = std::ptrdiff_t;
88 
91  return _currTimeCode;
92  }
93 
96  return &_currTimeCode;
97  }
98 
104  if (_timeCodeRange) {
105  ++_currStep;
106  _currTimeCode =
107  UsdTimeCode(
108  _timeCodeRange->_startTimeCode.GetValue() +
109  _timeCodeRange->_stride * _currStep);
110  }
111  _InvalidateIfExhausted();
112  return *this;
113  }
114 
120  const_iterator preAdvanceIter = *this;
121  ++(*this);
122  return preAdvanceIter;
123  }
124 
126  bool operator ==(const const_iterator& other) const {
127  return _timeCodeRange == other._timeCodeRange &&
128  _currStep == other._currStep;
129  }
130 
132  bool operator !=(const const_iterator& other) const {
133  return !(*this == other);
134  }
135 
136  private:
137  friend class UsdUtilsTimeCodeRange;
138 
139  const_iterator(const UsdUtilsTimeCodeRange* timeCodeRange) :
140  _timeCodeRange(timeCodeRange),
141  _currStep(0u),
142  _maxSteps(0u),
143  _currTimeCode()
144  {
145  if (_timeCodeRange) {
146  const double startVal = _timeCodeRange->_startTimeCode.GetValue();
147  const double endVal = _timeCodeRange->_endTimeCode.GetValue();
148  const double stride = _timeCodeRange->_stride;
149 
150  _maxSteps = static_cast<size_t>(
151  GfFloor((endVal - startVal + stride) / stride));
152  _currTimeCode = _timeCodeRange->_startTimeCode;
153  }
154 
155  _InvalidateIfExhausted();
156  }
157 
158  void _InvalidateIfExhausted() {
159  bool finished = false;
160  if (!_timeCodeRange) {
161  finished = true;
162  } else if (_currStep >= _maxSteps) {
163  finished = true;
164  }
165 
166  if (finished) {
167  _timeCodeRange = nullptr;
168  _currStep = 0u;
169  _maxSteps = 0u;
170  _currTimeCode = UsdTimeCode();
171  }
172  }
173 
174  const UsdUtilsTimeCodeRange* _timeCodeRange;
175  size_t _currStep;
176  size_t _maxSteps;
177  UsdTimeCode _currTimeCode;
178  };
179 
180  using iterator = const_iterator;
181 
211  USDUTILS_API
213  const std::string& frameSpec);
214 
220  {
221  _Invalidate();
222  }
223 
228  UsdUtilsTimeCodeRange(timeCode, timeCode)
229  {
230  }
231 
238  const UsdTimeCode startTimeCode,
239  const UsdTimeCode endTimeCode) :
241  startTimeCode,
242  endTimeCode,
243  (endTimeCode >= startTimeCode) ? 1.0 : -1.0)
244  {
245  }
246 
258  const UsdTimeCode startTimeCode,
259  const UsdTimeCode endTimeCode,
260  const double stride) :
261  _startTimeCode(startTimeCode),
262  _endTimeCode(endTimeCode),
263  _stride(stride)
264  {
265  if (_startTimeCode.IsEarliestTime()) {
267  "startTimeCode cannot be UsdTimeCode::EarliestTime()");
268  _Invalidate();
269  return;
270  }
271  if (_startTimeCode.IsDefault()) {
273  "startTimeCode cannot be UsdTimeCode::Default()");
274  _Invalidate();
275  return;
276  }
277  if (_endTimeCode.IsEarliestTime()) {
279  "endTimeCode cannot be UsdTimeCode::EarliestTime()");
280  _Invalidate();
281  return;
282  }
283  if (_endTimeCode.IsDefault()) {
285  "endTimeCode cannot be UsdTimeCode::Default()");
286  _Invalidate();
287  return;
288  }
289 
290  if (_stride > 0.0) {
291  if (_endTimeCode < _startTimeCode) {
293  "endTimeCode cannot be less than startTimeCode with "
294  "positive stride");
295  _Invalidate();
296  return;
297  }
298  } else if (_stride < 0.0) {
299  if (_endTimeCode > _startTimeCode) {
301  "endTimeCode cannot be greater than startTimeCode with "
302  "negative stride");
303  _Invalidate();
304  return;
305  }
306  } else {
307  TF_CODING_ERROR("stride cannot be zero");
308  _Invalidate();
309  return;
310  }
311  }
312 
315  return _startTimeCode;
316  }
317 
320  return _endTimeCode;
321  }
322 
324  double GetStride() const {
325  return _stride;
326  }
327 
329  iterator begin() const {
330  return iterator(this);
331  }
332 
335  return const_iterator(this);
336  }
337 
339  iterator end() const {
340  return iterator(nullptr);
341  }
342 
345  return const_iterator(nullptr);
346  }
347 
349  bool empty() const {
350  return begin() == end();
351  }
352 
355  bool IsValid() const {
356  return !empty();
357  }
358 
361  explicit operator bool() const {
362  return IsValid();
363  }
364 
366  bool operator ==(const UsdUtilsTimeCodeRange& other) const {
367  return _startTimeCode == other._startTimeCode &&
368  _endTimeCode == other._endTimeCode &&
369  _stride == other._stride;
370  }
371 
373  bool operator !=(const UsdUtilsTimeCodeRange& other) const {
374  return !(*this == other);
375  }
376 
377 private:
378 
380  void _Invalidate() {
381  _startTimeCode = UsdTimeCode(0.0);
382  _endTimeCode = UsdTimeCode(-1.0);
383  _stride = 1.0;
384  }
385 
386  UsdTimeCode _startTimeCode;
387  UsdTimeCode _endTimeCode;
388  double _stride;
389 };
390 
391 // Stream I/O operators.
392 
394 USDUTILS_API
395 std::ostream& operator<<(
396  std::ostream& os,
397  const UsdUtilsTimeCodeRange& timeCodeRange);
398 
400 USDUTILS_API
401 std::istream& operator>>(
402  std::istream& is,
403  UsdUtilsTimeCodeRange& timeCodeRange);
404 
405 
406 PXR_NAMESPACE_CLOSE_SCOPE
407 
408 
409 #endif
bool empty() const
Return true if this range contains no time codes, or false otherwise.
bool IsValid() const
Return true if this range contains one or more time codes, or false otherwise.
UsdUtilsTimeCodeRange(const UsdTimeCode timeCode)
Construct a range containing only the given timeCode.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:87
double GfFloor(double f)
Return floor(f).
Definition: math.h:98
bool operator!=(const const_iterator &other) const
Return true if this iterator is not equivalent to other.
bool operator==(const UsdUtilsTimeCodeRange &other) const
Return true if this range is equivalent to other.
bool IsDefault() const
Return true if this time represents the &#39;default&#39; sentinel value, false otherwise.
Definition: timeCode.h:140
double GetValue() const
Return the numeric value for this time.
Definition: timeCode.h:152
UsdUtilsTimeCodeRange()
Construct an invalid empty range.
iterator begin() const
Return an iterator to the start of this range.
Represents a range of UsdTimeCode values as start and end time codes and a stride value...
Definition: timeCodeRange.h:73
const_iterator cend() const
Return the past-the-end const_iterator for this range.
iterator end() const
Return the past-the-end iterator for this range.
bool operator!=(const UsdUtilsTimeCodeRange &other) const
Return true if this range is not equivalent to other.
Represent a time value, which may be either numeric, holding a double value, or a sentinel value UsdT...
Definition: timeCode.h:85
#define TF_DECLARE_PUBLIC_TOKENS(...)
Macro to define public tokens.
Definition: staticTokens.h:118
bool IsEarliestTime() const
Return true if this time represents the lowest/earliest possible timeCode, false otherwise.
Definition: timeCode.h:134
reference operator*()
Returns the UsdTimeCode referenced by this iterator.
Definition: timeCodeRange.h:90
UsdUtilsTimeCodeRange(const UsdTimeCode startTimeCode, const UsdTimeCode endTimeCode)
Construct a range containing the time codes from startTimeCode to endTimeCode.
USDUTILS_API std::istream & operator>>(std::istream &is, UsdUtilsTimeCodeRange &timeCodeRange)
Stream extraction operator.
A forward iterator into a UsdUtilsTimeCodeRange.
Definition: timeCodeRange.h:80
const_iterator operator++(int)
Post-increment operator.
const_iterator cbegin() const
Return a const_iterator to the start of this range.
pointer operator->()
Returns a pointer to the UsdTimeCode referenced by this iterator.
Definition: timeCodeRange.h:95
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
bool operator==(const const_iterator &other) const
Return true if this iterator is equivalent to other.
UsdTimeCode GetStartTimeCode() const
Return the start time code of this range.
UsdTimeCode GetEndTimeCode() const
Return the end time code of this range.
UsdUtilsTimeCodeRange(const UsdTimeCode startTimeCode, const UsdTimeCode endTimeCode, const double stride)
Construct a range containing the time codes from startTimeCode to endTimeCode using the stride value ...
static USDUTILS_API UsdUtilsTimeCodeRange CreateFromFrameSpec(const std::string &frameSpec)
Create a time code range from frameSpec.
const_iterator & operator++()
Pre-increment operator.
double GetStride() const
Return the stride value of this range.