HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
spline.h
Go to the documentation of this file.
1 //
2 // Copyright 2023 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 
25 #ifndef PXR_BASE_TS_SPLINE_H
26 #define PXR_BASE_TS_SPLINE_H
27 
28 #include "pxr/pxr.h"
29 #include "pxr/base/ts/api.h"
30 #include "pxr/base/ts/keyFrame.h"
32 #include "pxr/base/ts/types.h"
33 #include "pxr/base/ts/loopParams.h"
34 #include "pxr/base/vt/value.h"
35 
36 #include <vector>
37 #include <limits>
38 #include <map>
39 #include <typeinfo>
40 #include <iostream>
41 #include <optional>
42 
44 
45 class TsSpline_KeyFrames;
46 
47 /// \class TsSpline
48 ///
49 /// Represents a spline value object.
50 ///
51 /// The TsSpline class defines spline representations. Use this class to
52 /// define and manipulate avars over time. An TsSpline object is an
53 /// anonymous value that can be freely passed around. It has no owning object.
54 ///
55 /// Internally TsSpline is copy-on-write. This means that making a copy
56 /// of an TsSpline is nearly free in both time and memory, but making an
57 /// edit to a copy of an TsSpline may incur the cost of copying all the
58 /// data.
59 ///
60 /// TsSpline provides the basic thread safety guarantee: Multiple threads
61 /// may read and copy an TsSpline object concurrently, but it's not safe
62 /// to read from an TsSpline which another thread is concurrently writing
63 /// to. Internally that means that any data which may be mutated by a const
64 /// accessor must be protected by a mutex. Currently TsSpline has an immutable
65 /// lock-free implementation.
66 ///
67 class TsSpline final
68 {
69 public:
70  /// Constructs a spline with no key frames and held extrapolation.
71  TS_API
72  TsSpline();
73 
74  /// Copy construct.
75  TS_API
76  TsSpline(const TsSpline &other);
77 
78  /// Constructs a spline with the key frames \e keyFrames,
79  /// and optionally given extrapolation and looping parameters.
80  TS_API
81  explicit TsSpline( const TsKeyFrameMap & keyFrames,
82  TsExtrapolationType leftExtrapolation = TsExtrapolationHeld,
83  TsExtrapolationType rightExtrapolation = TsExtrapolationHeld,
84  const TsLoopParams &loopParams = TsLoopParams());
85 
86  /// Constructs a spline with the key frames \e keyFrames,
87  /// and optionally given extrapolation and looping parameters.
88  TS_API
89  explicit TsSpline( const std::vector<TsKeyFrame> & keyFrames,
90  TsExtrapolationType leftExtrapolation = TsExtrapolationHeld,
91  TsExtrapolationType rightExtrapolation = TsExtrapolationHeld,
92  const TsLoopParams &loopParams = TsLoopParams());
93 
94  /// Equality operator.
95  TS_API
96  bool operator==(const TsSpline &rhs) const;
97 
98  /// Inequality operator.
99  TS_API
100  bool operator!=(const TsSpline &rhs) const;
101 
102  /// Returns whether there are any keyframes.
103  TS_API
104  bool IsEmpty() const;
105 
106  /// Replaces the KeyFrames in this TsSpline with those in
107  /// swapInto, and puts the KeyFrames in this TsSpline into
108  /// swapInto. Requires that the vectors in swapInto are sorted
109  /// in ascending order according to their time.
110  TS_API
111  void SwapKeyFrames(std::vector<TsKeyFrame>* swapInto);
112 
113  /// Removes redundant keyframes from the spline in the specified
114  /// multi-interval.
115  /// \return True if the spline was changed, false if not.
116  /// \param defaultValue Used only to decide whether to remove the final
117  /// keyframe. The final keyframe is removed if defaultValue is specified
118  /// and the final keyframe has this value.
119  /// \param intervals Only keyframes in the given multiInterval will be
120  /// removed, although all keyframes will be considered in computing what
121  /// is redundant.
122  TS_API
123  bool ClearRedundantKeyFrames( const VtValue &defaultValue = VtValue(),
124  const GfMultiInterval &intervals =
126  -std::numeric_limits<double>::infinity(),
127  std::numeric_limits<double>::infinity())));
128 
129 
130  /// Returns the keyframes in this spline.
131  ///
132  /// Note that any non-const method invalidates the reference to
133  /// the KeyFrameMap. Do not hold on to the KeyFrameMap reference,
134  /// make a modification to the spline, and then use the original
135  /// KeyFrameMap reference.
136  TS_API
137  const TsKeyFrameMap& GetKeyFrames() const;
138 
139  /// Returns the "raw" keyframes in this spline whether or not this
140  /// spline is looping. Note that this method is the sole exception to the
141  /// rule that the API presents the looped view of the spline when it is
142  /// a looping spline.
143  ///
144  /// Note that any non-const method invalidates the reference to
145  /// the KeyFrameMap. Do not hold on to the KeyFrameMap reference,
146  /// make a modification to the spline, and then use the original
147  /// KeyFrameMap reference.
148  TS_API
149  const TsKeyFrameMap& GetRawKeyFrames() const;
150 
151  /// Returns the keyframes contained in the given GfMultiInterval.
152  TS_API
153  std::vector<TsKeyFrame>
155 
156  /// Returns the minimum and maximum keyframe frames in the spline. If there
157  /// are no keyframes, the returned range will be empty.
158  TS_API
159  GfInterval GetFrameRange() const;
160 
161  /// Sets a keyframe, optionally returning the time range affected.
162  /// If a keyframe already exists at the specified time, it will be
163  /// replaced. If the keyframe is not a valid type to set, an error
164  /// will be emitted; to avoid this, call CanSetKeyFrame() first.
165  TS_API
166  void SetKeyFrame(
167  TsKeyFrame kf, GfInterval *intervalAffected=nullptr );
168 
169  /// Checks if the given keyframe is a valid candidate to set,
170  /// optionally returning the reason if it cannot.
171  TS_API
172  bool CanSetKeyFrame(
173  const TsKeyFrame & kf, std::string *reason=nullptr ) const;
174 
175  /// \brief Breakdown at time \e x.
176  ///
177  /// If a key frame exists at \e x then this does nothing, otherwise it
178  /// inserts a key frame of type \e type at \e x. If the provided \e value is
179  /// empty (the default), the new key frame's value is chosen such that the
180  /// value at \e x doesn't change. If \e value is not empty, the new keyframe
181  /// is always given that value.
182  ///
183  /// If \e flatTangents is \c false and \e x is between the first and last
184  /// key frames then it will also try to preserve the shape of the spline as
185  /// much as possible. Otherwise, if the key frame type and value type
186  /// support tangents, the key frame will have tangents with zero slope and
187  /// length \e tangentLength.
188  ///
189  /// The return value is either the newly broken down keyframe, or the
190  /// existing keyframe at the given time. If an error has occurred, an
191  /// empty value may be returned.
192  TS_API
193  std::optional<TsKeyFrame>
194  Breakdown( double x, TsKnotType type,
195  bool flatTangents, double tangentLength,
196  const VtValue &value = VtValue(),
197  GfInterval *intervalAffected=nullptr );
198 
199  /// Breaks down simultaneously at several times.
200  ///
201  /// When creating knots with flat tangents, the shape of the spline may
202  /// change between the new knot and its adjacent knots. Simply breaking
203  /// down a spline several times in a loop may result in key frame values
204  /// that drift away from their original values. This function samples the
205  /// spline first, ensuring that each new key frame will preserve the value
206  /// at that time.
207  ///
208  /// If \e value is not empty, \e value is used instead of sampling the
209  /// spline. For each time, if there is already a key frame at that time, the
210  /// value and type of that keyframe will not be changed.
211  ///
212  /// The arguments are the same as Breakdown(). If \p keyFramesAtTimes is
213  /// given, it will be populated with the newly broken down or previously
214  /// existing key frames at the given times.
215  TS_API
216  void
217  Breakdown( const std::set<double> & times, TsKnotType type,
218  bool flatTangents, double tangentLength,
219  const VtValue &value = VtValue(),
220  GfInterval *intervalAffected=nullptr,
221  TsKeyFrameMap *keyFramesAtTimes=nullptr);
222 
223  /// Breaks down simultaneously at several times.
224  ///
225  /// Caller can provide a value for each time. If a value is not provided
226  /// at a given time (it is empty), this function will sample the spline.
227  /// If a knot already exists at a given time, its value is not modified.
228  ///
229  /// The arguments are the same as Breakdown(). If \p keyFramesAtTimes is
230  /// given, it will be populated with the newly broken down or previously
231  /// existing key frames at the given times.
232  TS_API
233  void
234  Breakdown( const std::vector<double> & times, TsKnotType type,
235  bool flatTangents, double tangentLength,
236  const std::vector<VtValue> & values,
237  GfInterval *intervalAffected=nullptr,
238  TsKeyFrameMap *keyFramesAtTimes=nullptr);
239 
240  /// Breaks down simultaneously at several times with knot types specified
241  /// for each time.
242  ///
243  /// A knot type for each time must be provided, else it is a coding error.
244  ///
245  /// Caller can provide a value for each time. If a value is not provided
246  /// at a given time (it is empty), this function will sample the spline.
247  /// If a knot already exists at a given time, its value is not modified.
248  ///
249  /// The arguments are the same as Breakdown(). If \p keyFramesAtTimes is
250  /// given, it will be populated with the newly broken down or previously
251  /// existing key frames at the given times.
252  TS_API
253  void
254  Breakdown( const std::vector<double> & times,
255  const std::vector<TsKnotType> & types,
256  bool flatTangents, double tangentLength,
257  const std::vector<VtValue> & values,
258  GfInterval *intervalAffected=nullptr,
259  TsKeyFrameMap *keyFramesAtTimes=nullptr);
260 
261  /// Removes the keyframe at the given time, optionally returning the
262  /// time range affected.
263  TS_API
264  void RemoveKeyFrame(
265  TsTime time, GfInterval *intervalAffected=nullptr);
266 
267  /// Removes all keyframes. This does not affect extrapolation. If this
268  /// spline is looping, knots hidden under the loop echos will not be
269  /// removed.
270  TS_API
271  void Clear();
272 
273  /// \brief Finds the keyframe closest to the given time.
274  /// Returns an empty value if there are no keyframes.
275  TS_API
276  std::optional<TsKeyFrame>
277  GetClosestKeyFrame( TsTime targetTime ) const;
278 
279  /// \brief Finds the closest keyframe before the given time.
280  /// Returns an empty value if no such keyframe exists.
281  TS_API
282  std::optional<TsKeyFrame>
283  GetClosestKeyFrameBefore( TsTime targetTime )const;
284 
285  /// \brief Finds the closest keyframe after the given time.
286  /// Returns an empty value if no such keyframe exists.
287  TS_API
288  std::optional<TsKeyFrame>
289  GetClosestKeyFrameAfter( TsTime targetTime ) const;
290 
291  /// \brief Returns true if the given key frame is redundant.
292  ///
293  /// A key frame is redundant if it can be removed without affecting the
294  /// value of the spline at any time. If a spline has only one key frame
295  /// and that key frame has the same value as this spline's default
296  /// value, then that key frame is considered redundant. If a
297  /// \c defaultValue parameter is not supplied, the last knot on a spline
298  /// is never considered redundant.
299  TS_API
300  bool IsKeyFrameRedundant( const TsKeyFrame &keyFrame,
301  const VtValue &defaultValue = VtValue() ) const;
302 
303  /// \brief Returns true if the key frame at the given time is redundant.
304  ///
305  /// This is a convenience function for the version that takes a
306  /// TsKeyFrame. If there is no key frame at the indicated time a
307  /// TF_CODING_ERROR will occur and false is returned.
308  TS_API
309  bool IsKeyFrameRedundant( TsTime keyFrameTime,
310  const VtValue &defaultValue = VtValue() ) const;
311 
312  /// \brief Returns true if any of this spline's key frames are redundant.
313  TS_API
314  bool HasRedundantKeyFrames( const VtValue &defaultValue = VtValue() ) const;
315 
316  /// \brief Returns true if the segment between the given (adjacent) key
317  /// frames is flat.
318  TS_API
319  bool IsSegmentFlat( const TsKeyFrame &kf1,
320  const TsKeyFrame &kf2 ) const;
321 
322  /// \brief Returns true if the segment between the given (adjacent) key
323  /// frames is flat.
324  ///
325  /// This function will log a TF_CODING_ERROR if there is no key frame at
326  /// either of the indicated times.
327  TS_API
328  bool IsSegmentFlat( TsTime startTime, TsTime endTime ) const;
329 
330  /// \brief Returns true if the segment between the given (adjacent) key
331  /// frames is monotonic (i.e. no extremes).
332  ///
333  /// This function will log a TF_CODING_ERROR if kf1 >= kf2
334  /// TODO describe the preconditions
335  ///
336  TS_API
337  bool
338  IsSegmentValueMonotonic( const TsKeyFrame &kf1,
339  const TsKeyFrame &kf2 ) const;
340 
341  /// \brief Returns true if the segment between the given (adjacent) key
342  /// frames is monotonic (i.e. no extremes).
343  ///
344  /// Given times must correspond to key frames.
345  /// see also IsSegmentValueMonotonic(kf1, kf2)
346  TS_API
347  bool
348  IsSegmentValueMonotonic( TsTime startTime, TsTime endTime ) const;
349 
350  /// \brief Returns true if the value of the spline changes over time,
351  /// whether due to differing values among keyframes or knot sides,
352  /// or value changes via non-flat tangents. If allowEpsilonDifferences is
353  /// true, then if the spline is of type double, then knot value
354  /// differences that are tiny will count as 0.
355  TS_API
356  bool
357  IsVarying() const;
358 
359  /// \brief Like IsVarying(), but for splines of type double, allows tiny
360  /// value differences.
361  TS_API
362  bool
363  IsVaryingSignificantly() const;
364 
365  /// Sets the spline's extrapolation type on each side.
366  TS_API
367  void SetExtrapolation(
369 
370  /// Returns the spline's extrapolation type on each side (\c first
371  /// is the left side).
372  TS_API
373  std::pair<TsExtrapolationType, TsExtrapolationType>
374  GetExtrapolation() const;
375 
376  /// Returns the typeid of the value type for keyframes in this spline.
377  /// If no keyframes have been set, this will return typeid(void).
378  TS_API
379  const std::type_info &
380  GetTypeid() const;
381 
382  /// Returns the TfType of the value type for keyframes in this spline.
383  /// If no keyframes have been set, this will return unknown type
384  TS_API
385  TfType
386  GetType() const;
387 
388  /// Returns the typename of the value type for keyframes in this spline,
389  /// If no keyframes have been set, this will return "void".
390  TS_API
391  std::string GetTypeName() const;
392 
393  /// Evaluates the value of the spline at the given time, interpolating the
394  /// keyframes. If there are no keyframes, an empty VtValue is returned.
395  TS_API
396  VtValue Eval(
397  TsTime time, TsSide side=TsRight ) const;
398 
399  /// Evaluates the value of the spline at the given time without any
400  /// interpolation, as if all keyframes and extrapolation modes were of
401  /// type "held".
402  ///
403  /// If there are no keyframes, an empty VtValue is returned.
404  TS_API
405  VtValue EvalHeld( TsTime time, TsSide side=TsRight ) const;
406 
407  /// Evaluates the derivative of the spline at the given time, interpolating
408  /// the keyframes. If there are no keyframes, an empty VtValue is returned.
409  TS_API
411  TsTime time, TsSide side=TsRight ) const;
412 
413  /// Returns whether the left-side value and the right-side value at the
414  /// specified time are different. This is always false for a time where
415  /// there is no keyframe. For a keyframe time, the sides differ if (1)
416  /// there is a dual-valued keyframe with different values on the left and
417  /// right side; or (2) the keyframe follows a held segment whose value does
418  /// not match the keyframe's right-side value. Contrast this method with
419  /// TsKeyFrame::GetIsDualValued, which only reports whether a keyframe is
420  /// configured to have dual values.
421  TS_API
422  bool DoSidesDiffer(TsTime time) const;
423 
424  /// \brief Evaluates the value of the spline over the given time interval.
425  /// When the returned samples are scaled by \e timeScale and
426  /// \e valueScale and linearly interpolated, the reconstructed curve
427  /// will nowhere have an error greater than \e tolerance.
428  ///
429  /// Samples may be point samples or "blur" samples. A blur sample
430  /// covers a finite time domain and a value range. It indicates that
431  /// the value varies very quickly in the domain and that, to the given
432  /// tolerance, only the minimum and maximum values are of interest.
433  /// Blur domains are always half-open on the right.
434  ///
435  /// Samples are returned in non-decreasing time order. Two samples
436  /// may have equal time in two cases. First, if both are point samples
437  /// then the first is the left side evaluation of the value at time
438  /// and the second is the right side evaluation. Second, if the first
439  /// sample is a point sample and second is a blur sample then the point
440  /// sample is the left side evaluation of time. Blur domains will not
441  /// overlap and point samples, with the above exception, will not be
442  /// inside any blur domain.
443  ///
444  /// Samples may be returned outside the given time interval.
445  TS_API
447  TsTime startTime, TsTime endTime,
448  double timeScale, double valueScale,
449  double tolerance ) const;
450 
451  TS_API
452  std::pair<VtValue, VtValue>
453  GetRange( TsTime startTime, TsTime endTime ) const;
454 
455  /// Returns whether spline represents a simple linear relationship.
456  TS_API
457  bool IsLinear() const;
458 
459  /// Returns whether the given key frame is in the looped interval, but
460  /// not in the master interval.
461  TS_API
462  bool KeyFrameIsInLoopedRange(const TsKeyFrame & kf);
463 
464  /// \brief Return an object describing all the looping parameters for
465  /// this spline.
466  TS_API
467  TsLoopParams GetLoopParams() const;
468 
469  /// \brief Set the looping parameters for this spline.
470  TS_API
471  void SetLoopParams(const TsLoopParams&);
472 
473  // If this spline is a looping spline, bakes the looped key frames
474  // out and turns looping off. Hidden keyframes will be lost.
475  TS_API
476  void BakeSplineLoops();
477 
478  /// \brief Is the given time in the "unrolled" region of a spline that is
479  /// looping; i.e. not in the master region
480  TS_API
481  bool IsTimeLooped(TsTime time) const;
482 
483  /// Our iterators are simply iterators into the contained TsKeyFrameMap
484  /// We only expose const iterators because when a KeyFrame changes we
485  /// need to update other internal state.
488 
489  /// Some utilities (such as TfIterator) expect a class named 'iterator'.
490  /// We provide that as a typdef to const_iterator in order to avoid exposing
491  /// real non-const iterators.
494 
495  /// \group Container API
496  ///
497  /// Provide STL container compliant API.
498  ///
499  /// Some of these methods are inlined because they are often called
500  /// as part of looping constructions where the cost of function calls
501  /// could be high.
502  /// @{
503 
504  /// Returns the number of KeyFrames in this spline.
505  TS_API
506  size_t size() const {
507  return GetKeyFrames().size();
508  }
509 
510  /// Return true if this spline has no KeyFrames.
511  TS_API
512  bool empty() const {
513  return GetKeyFrames().empty();
514  }
515 
516  /// Return a const_iterator pointing to the beginning of the spline.
517  TS_API
519  return const_iterator(GetKeyFrames().begin());
520  }
521 
522  /// Returns a const_iterator pointing to the end of the spline. (one past
523  /// the last KeyFrame)
524  TS_API
525  const_iterator end() const {
526  return const_iterator(GetKeyFrames().end());
527  }
528 
529  /// Return a const_reverse_iterator pointing to the end of the spline.
530  TS_API
533  }
534 
535  /// Returns a const_reverse_iterator pointing to the beginning of the
536  /// spline. (one before the first KeyFrame)
537  TS_API
540  }
541 
542 
543  /// Returns a const_iterator to the KeyFrame at time \p t. This
544  /// will return end() if no KeyFrame exists at that time.
545  TS_API
546  const_iterator find(const TsTime &t) const;
547 
548  /// Returns a const_iterator to the first KeyFrame with a time
549  /// that is not less than \p t.
550  TS_API
551  const_iterator lower_bound(const TsTime &t) const;
552 
553  /// Returns a const_iterator to the first KeyFrame with a time
554  /// that is greater than \p t.
555  TS_API
556  const_iterator upper_bound(const TsTime &t) const;
557 
558  /// Returns the number (either 0 or 1) of KeyFrames with time
559  /// \p t.
560  TS_API
561  size_t count(const TsTime &t) const {
562  return GetKeyFrames().find(t) != GetKeyFrames().end();
563  }
564 
565  /// @}
566 
567 private:
568 
569  void _BreakdownMultipleValues( const std::vector<double> &times,
570  TsKnotType type, bool flatTangents, double tangentLength,
571  const std::vector<VtValue> &values,
572  GfInterval *intervalAffected,
573  TsKeyFrameMap *keyFramesAtTimes);
574 
575  void _BreakdownMultipleKnotTypes( const std::vector<double> &times,
576  const std::vector<TsKnotType> &types,
577  bool flatTangents, double tangentLength,
578  const std::vector<VtValue> &values,
579  GfInterval *intervalAffected,
580  TsKeyFrameMap *keyFramesAtTimes);
581 
582  // Fills \p keyframes with the new keyframes to effect a breakdown
583  // at \p x. Subclasses can use this to implement \c Breakdown();
584  // they'll call this then set each key frame in \p keyframes.
585  void
586  _GetBreakdown( TsKeyFrameMap* newKeyframes, double x, TsKnotType type,
587  bool flatTangents, double tangentLength,
588  const VtValue &value ) const;
589 
590  typedef std::vector<std::pair<TsTime, VtValue>> _Samples;
591 
592  // Helper for _BreakdownMultipleKnotTypes. Performs the Breakdown on the
593  // given list of samples, i.e. time/value pairs.
594  void _BreakdownSamples(
595  const _Samples &samples,
596  TsKnotType type,
597  bool flatTangents,
598  double tangentLength,
599  GfInterval *intervalAffected,
600  TsKeyFrameMap *keyFramesAtTimes);
601 
602  // Helper for the forms of IsVarying*; allows subseqent keyframes to vary
603  // by 'tolerance'.
604  bool _IsVarying(double tolerance) const;
605 
606  /// Ensure that _data is not shared with any other spline.
607  /// If it is, make our own copy and drop our reference to the shared one.
608  void _Detach();
609 
610 private:
611  std::shared_ptr<TsSpline_KeyFrames> _data;
612 };
613 
614 TS_API
615 std::ostream& operator<<(std::ostream &out, const TsSpline &val);
616 
618 
619 #endif
TsExtrapolationType
Spline extrapolation types.
Definition: types.h:77
TS_API size_t count(const TsTime &t) const
Definition: spline.h:561
TS_API size_t size() const
Definition: keyFrameMap.h:114
TS_API std::ostream & operator<<(std::ostream &out, const TsSpline &val)
TS_API TfType GetType() const
Held; splines hold values at edges.
Definition: types.h:78
TS_API bool IsTimeLooped(TsTime time) const
Is the given time in the "unrolled" region of a spline that is looping; i.e. not in the master region...
TS_API std::optional< TsKeyFrame > GetClosestKeyFrameBefore(TsTime targetTime) const
Finds the closest keyframe before the given time. Returns an empty value if no such keyframe exists...
TS_API bool ClearRedundantKeyFrames(const VtValue &defaultValue=VtValue(), const GfMultiInterval &intervals=GfMultiInterval(GfInterval(-std::numeric_limits< double >::infinity(), std::numeric_limits< double >::infinity())))
TS_API const_iterator upper_bound(const TsTime &t) const
GLint left
Definition: glcorearb.h:2005
GT_API const UT_StringHolder time
TS_API bool empty() const
Definition: keyFrameMap.h:124
std::vector< TsKeyFrame >::const_iterator const_iterator
Definition: keyFrameMap.h:54
TS_API bool IsEmpty() const
Returns whether there are any keyframes.
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
TS_API const_iterator lower_bound(const TsTime &t) const
TS_API bool IsSegmentFlat(const TsKeyFrame &kf1, const TsKeyFrame &kf2) const
Returns true if the segment between the given (adjacent) key frames is flat.
TS_API std::vector< TsKeyFrame > GetKeyFramesInMultiInterval(const GfMultiInterval &) const
Returns the keyframes contained in the given GfMultiInterval.
TS_API iterator find(const TsTime &t)
Definition: keyFrameMap.h:181
GLdouble right
Definition: glad.h:2817
TS_API bool IsVaryingSignificantly() const
Like IsVarying(), but for splines of type double, allows tiny value differences.
TS_API bool DoSidesDiffer(TsTime time) const
TS_API bool IsKeyFrameRedundant(const TsKeyFrame &keyFrame, const VtValue &defaultValue=VtValue()) const
Returns true if the given key frame is redundant.
TS_API void SwapKeyFrames(std::vector< TsKeyFrame > *swapInto)
TS_API bool empty() const
Return true if this spline has no KeyFrames.
Definition: spline.h:512
const_iterator iterator
Definition: spline.h:492
TS_API const TsKeyFrameMap & GetRawKeyFrames() const
Definition: types.h:92
An ordered sequence of keyframes with STL-compliant API for finding, inserting, and erasing keyframes...
Definition: keyFrameMap.h:50
TS_API void SetExtrapolation(TsExtrapolationType left, TsExtrapolationType right)
Sets the spline's extrapolation type on each side.
TS_API VtValue Eval(TsTime time, TsSide side=TsRight) const
TS_API const TsKeyFrameMap & GetKeyFrames() const
TS_API iterator end()
Definition: keyFrameMap.h:84
const_reverse_iterator reverse_iterator
Definition: spline.h:493
TS_API const_iterator find(const TsTime &t) const
std::vector< TsKeyFrame >::const_reverse_iterator const_reverse_iterator
Definition: keyFrameMap.h:56
TsKnotType
Keyframe knot types.
Definition: types.h:64
TS_API bool IsSegmentValueMonotonic(const TsKeyFrame &kf1, const TsKeyFrame &kf2) const
Returns true if the segment between the given (adjacent) key frames is monotonic (i.e. no extremes).
std::vector< TsValueSample > TsSamples
A sequence of samples.
Definition: types.h:119
TS_API bool CanSetKeyFrame(const TsKeyFrame &kf, std::string *reason=nullptr) const
TS_API const_reverse_iterator rbegin() const
Return a const_reverse_iterator pointing to the end of the spline.
Definition: spline.h:531
TS_API VtValue EvalDerivative(TsTime time, TsSide side=TsRight) const
TS_API const_reverse_iterator rend() const
Definition: spline.h:538
TS_API std::optional< TsKeyFrame > Breakdown(double x, TsKnotType type, bool flatTangents, double tangentLength, const VtValue &value=VtValue(), GfInterval *intervalAffected=nullptr)
Breakdown at time x.
TsKeyFrameMap::const_reverse_iterator const_reverse_iterator
Definition: spline.h:487
TS_API std::pair< VtValue, VtValue > GetRange(TsTime startTime, TsTime endTime) const
Specifies the value of an TsSpline object at a particular point in time.
Definition: keyFrame.h:66
TS_API TsLoopParams GetLoopParams() const
Return an object describing all the looping parameters for this spline.
GLint GLenum GLint x
Definition: glcorearb.h:409
TS_API bool KeyFrameIsInLoopedRange(const TsKeyFrame &kf)
GLdouble t
Definition: glad.h:2397
TS_API const_iterator begin() const
Return a const_iterator pointing to the beginning of the spline.
Definition: spline.h:518
PXR_NAMESPACE_OPEN_SCOPE typedef double TsTime
The time type used by Ts.
Definition: types.h:57
TS_API GfInterval GetFrameRange() const
TS_API TsSpline()
Constructs a spline with no key frames and held extrapolation.
#define TS_API
Definition: api.h:41
GLsizei samples
Definition: glcorearb.h:1298
TS_API const std::type_info & GetTypeid() const
TS_API TsSamples Sample(TsTime startTime, TsTime endTime, double timeScale, double valueScale, double tolerance) const
Evaluates the value of the spline over the given time interval. When the returned samples are scaled ...
TS_API const_iterator end() const
Definition: spline.h:525
TsSide
Dual-value keyframe side.
Definition: types.h:90
TS_API std::string GetTypeName() const
TS_API void SetKeyFrame(TsKeyFrame kf, GfInterval *intervalAffected=nullptr)
TS_API bool operator!=(const TsSpline &rhs) const
Inequality operator.
TS_API bool operator==(const TsSpline &rhs) const
Equality operator.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
Maintains the keyframes for a spline.
TS_API std::optional< TsKeyFrame > GetClosestKeyFrameAfter(TsTime targetTime) const
Finds the closest keyframe after the given time. Returns an empty value if no such keyframe exists...
TS_API size_t size() const
Returns the number of KeyFrames in this spline.
Definition: spline.h:506
GLuint GLfloat * val
Definition: glcorearb.h:1608
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
TS_API void BakeSplineLoops()
TS_API bool IsLinear() const
Returns whether spline represents a simple linear relationship.
Definition: type.h:64
Definition: core.h:1131
TsKeyFrameMap::const_iterator const_iterator
Definition: spline.h:486
GLsizei GLenum GLenum * types
Definition: glcorearb.h:2542
TS_API bool IsVarying() const
Returns true if the value of the spline changes over time, whether due to differing values among keyf...
TS_API void Clear()
TS_API std::optional< TsKeyFrame > GetClosestKeyFrame(TsTime targetTime) const
Finds the keyframe closest to the given time. Returns an empty value if there are no keyframes...
type
Definition: core.h:1059
TS_API void RemoveKeyFrame(TsTime time, GfInterval *intervalAffected=nullptr)
TS_API std::pair< TsExtrapolationType, TsExtrapolationType > GetExtrapolation() const
Definition: value.h:164
TS_API bool HasRedundantKeyFrames(const VtValue &defaultValue=VtValue()) const
Returns true if any of this spline's key frames are redundant.
TS_API VtValue EvalHeld(TsTime time, TsSide side=TsRight) const
TS_API void SetLoopParams(const TsLoopParams &)
Set the looping parameters for this spline.