Loading...
Searching...
No Matches
spline.h
1//
2// Copyright 2023 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7
8#ifndef PXR_BASE_TS_SPLINE_H
9#define PXR_BASE_TS_SPLINE_H
10
11#include "pxr/pxr.h"
12#include "pxr/base/ts/api.h"
13#include "pxr/base/ts/keyFrame.h"
14#include "pxr/base/ts/keyFrameMap.h"
15#include "pxr/base/ts/types.h"
16#include "pxr/base/ts/loopParams.h"
17#include "pxr/base/vt/value.h"
18
19#include <vector>
20#include <limits>
21#include <map>
22#include <typeinfo>
23#include <iostream>
24#include <optional>
25
26PXR_NAMESPACE_OPEN_SCOPE
27
29
50class TsSpline final
51{
52public:
54 TS_API
56
58 TS_API
59 TsSpline(const TsSpline &other);
60
63 TS_API
64 explicit TsSpline( const TsKeyFrameMap & keyFrames,
65 TsExtrapolationType leftExtrapolation = TsExtrapolationHeld,
66 TsExtrapolationType rightExtrapolation = TsExtrapolationHeld,
67 const TsLoopParams &loopParams = TsLoopParams());
68
71 TS_API
72 explicit TsSpline( const std::vector<TsKeyFrame> & keyFrames,
73 TsExtrapolationType leftExtrapolation = TsExtrapolationHeld,
74 TsExtrapolationType rightExtrapolation = TsExtrapolationHeld,
75 const TsLoopParams &loopParams = TsLoopParams());
76
78 TS_API
79 bool operator==(const TsSpline &rhs) const;
80
82 TS_API
83 bool operator!=(const TsSpline &rhs) const;
84
86 TS_API
87 bool IsEmpty() const;
88
93 TS_API
94 void SwapKeyFrames(std::vector<TsKeyFrame>* swapInto);
95
105 TS_API
106 bool ClearRedundantKeyFrames( const VtValue &defaultValue = VtValue(),
107 const GfMultiInterval &intervals =
109 -std::numeric_limits<double>::infinity(),
110 std::numeric_limits<double>::infinity())));
111
112
119 TS_API
121
131 TS_API
133
135 TS_API
136 std::vector<TsKeyFrame>
138
141 TS_API
143
148 TS_API
150 TsKeyFrame kf, GfInterval *intervalAffected=nullptr );
151
154 TS_API
156 const TsKeyFrame & kf, std::string *reason=nullptr ) const;
157
175 TS_API
176 std::optional<TsKeyFrame>
177 Breakdown( double x, TsKnotType type,
178 bool flatTangents, double tangentLength,
179 const VtValue &value = VtValue(),
180 GfInterval *intervalAffected=nullptr );
181
198 TS_API
199 void
200 Breakdown( const std::set<double> & times, TsKnotType type,
201 bool flatTangents, double tangentLength,
202 const VtValue &value = VtValue(),
203 GfInterval *intervalAffected=nullptr,
204 TsKeyFrameMap *keyFramesAtTimes=nullptr);
205
215 TS_API
216 void
217 Breakdown( const std::vector<double> & times, TsKnotType type,
218 bool flatTangents, double tangentLength,
219 const std::vector<VtValue> & values,
220 GfInterval *intervalAffected=nullptr,
221 TsKeyFrameMap *keyFramesAtTimes=nullptr);
222
235 TS_API
236 void
237 Breakdown( const std::vector<double> & times,
238 const std::vector<TsKnotType> & types,
239 bool flatTangents, double tangentLength,
240 const std::vector<VtValue> & values,
241 GfInterval *intervalAffected=nullptr,
242 TsKeyFrameMap *keyFramesAtTimes=nullptr);
243
246 TS_API
248 TsTime time, GfInterval *intervalAffected=nullptr);
249
253 TS_API
254 void Clear();
255
258 TS_API
259 std::optional<TsKeyFrame>
260 GetClosestKeyFrame( TsTime targetTime ) const;
261
264 TS_API
265 std::optional<TsKeyFrame>
266 GetClosestKeyFrameBefore( TsTime targetTime )const;
267
270 TS_API
271 std::optional<TsKeyFrame>
272 GetClosestKeyFrameAfter( TsTime targetTime ) const;
273
282 TS_API
283 bool IsKeyFrameRedundant( const TsKeyFrame &keyFrame,
284 const VtValue &defaultValue = VtValue() ) const;
285
291 TS_API
292 bool IsKeyFrameRedundant( TsTime keyFrameTime,
293 const VtValue &defaultValue = VtValue() ) const;
294
296 TS_API
297 bool HasRedundantKeyFrames( const VtValue &defaultValue = VtValue() ) const;
298
301 TS_API
302 bool IsSegmentFlat( const TsKeyFrame &kf1,
303 const TsKeyFrame &kf2 ) const;
304
310 TS_API
311 bool IsSegmentFlat( TsTime startTime, TsTime endTime ) const;
312
319 TS_API
320 bool
322 const TsKeyFrame &kf2 ) const;
323
329 TS_API
330 bool
331 IsSegmentValueMonotonic( TsTime startTime, TsTime endTime ) const;
332
338 TS_API
339 bool
340 IsVarying() const;
341
344 TS_API
345 bool
347
349 TS_API
351 TsExtrapolationType left, TsExtrapolationType right);
352
355 TS_API
356 std::pair<TsExtrapolationType, TsExtrapolationType>
358
361 TS_API
362 const std::type_info &
363 GetTypeid() const;
364
367 TS_API
368 TfType
369 GetType() const;
370
373 TS_API
374 std::string GetTypeName() const;
375
378 TS_API
380 TsTime time, TsSide side=TsRight ) const;
381
387 TS_API
388 VtValue EvalHeld( TsTime time, TsSide side=TsRight ) const;
389
392 TS_API
394 TsTime time, TsSide side=TsRight ) const;
395
404 TS_API
405 bool DoSidesDiffer(TsTime time) const;
406
428 TS_API
429 TsSamples Sample(
430 TsTime startTime, TsTime endTime,
431 double timeScale, double valueScale,
432 double tolerance ) const;
433
434 TS_API
435 std::pair<VtValue, VtValue>
436 GetRange( TsTime startTime, TsTime endTime ) const;
437
439 TS_API
440 bool IsLinear() const;
441
444 TS_API
446
449 TS_API
450 TsLoopParams GetLoopParams() const;
451
453 TS_API
454 void SetLoopParams(const TsLoopParams&);
455
456 // If this spline is a looping spline, bakes the looped key frames
457 // out and turns looping off. Hidden keyframes will be lost.
458 TS_API
459 void BakeSplineLoops();
460
463 TS_API
464 bool IsTimeLooped(TsTime time) const;
465
469 typedef TsKeyFrameMap::const_iterator const_iterator;
470 typedef TsKeyFrameMap::const_reverse_iterator const_reverse_iterator;
471
476 typedef const_reverse_iterator reverse_iterator;
477
486
488 TS_API
489 size_t size() const {
490 return GetKeyFrames().size();
491 }
492
494 TS_API
495 bool empty() const {
496 return GetKeyFrames().empty();
497 }
498
500 TS_API
503 }
504
507 TS_API
509 return const_iterator(GetKeyFrames().end());
510 }
511
513 TS_API
514 const_reverse_iterator rbegin() const {
515 return const_reverse_iterator(GetKeyFrames().rbegin());
516 }
517
520 TS_API
521 const_reverse_iterator rend() const {
522 return const_reverse_iterator(GetKeyFrames().rend());
523 }
524
525
528 TS_API
529 const_iterator find(const TsTime &t) const;
530
533 TS_API
534 const_iterator lower_bound(const TsTime &t) const;
535
538 TS_API
539 const_iterator upper_bound(const TsTime &t) const;
540
543 TS_API
544 size_t count(const TsTime &t) const {
545 return GetKeyFrames().find(t) != GetKeyFrames().end();
546 }
547
549
550private:
551
552 void _BreakdownMultipleValues( const std::vector<double> &times,
553 TsKnotType type, bool flatTangents, double tangentLength,
554 const std::vector<VtValue> &values,
555 GfInterval *intervalAffected,
556 TsKeyFrameMap *keyFramesAtTimes);
557
558 void _BreakdownMultipleKnotTypes( const std::vector<double> &times,
559 const std::vector<TsKnotType> &types,
560 bool flatTangents, double tangentLength,
561 const std::vector<VtValue> &values,
562 GfInterval *intervalAffected,
563 TsKeyFrameMap *keyFramesAtTimes);
564
565 // Fills \p keyframes with the new keyframes to effect a breakdown
566 // at \p x. Subclasses can use this to implement \c Breakdown();
567 // they'll call this then set each key frame in \p keyframes.
568 void
569 _GetBreakdown( TsKeyFrameMap* newKeyframes, double x, TsKnotType type,
570 bool flatTangents, double tangentLength,
571 const VtValue &value ) const;
572
573 typedef std::vector<std::pair<TsTime, VtValue>> _Samples;
574
575 // Helper for _BreakdownMultipleKnotTypes. Performs the Breakdown on the
576 // given list of samples, i.e. time/value pairs.
577 void _BreakdownSamples(
578 const _Samples &samples,
579 TsKnotType type,
580 bool flatTangents,
581 double tangentLength,
582 GfInterval *intervalAffected,
583 TsKeyFrameMap *keyFramesAtTimes);
584
585 // Helper for the forms of IsVarying*; allows subseqent keyframes to vary
586 // by 'tolerance'.
587 bool _IsVarying(double tolerance) const;
588
591 void _Detach();
592
593private:
594 std::shared_ptr<TsSpline_KeyFrames> _data;
595};
596
597TS_API
598std::ostream& operator<<(std::ostream &out, const TsSpline &val);
599
600PXR_NAMESPACE_CLOSE_SCOPE
601
602#endif
A basic mathematical interval class.
Definition: interval.h:33
GfMultiInterval represents a subset of the real number line as an ordered set of non-intersecting GfI...
Definition: multiInterval.h:30
TfType represents a dynamic runtime type.
Definition: type.h:48
Specifies the value of an TsSpline object at a particular point in time.
Definition: keyFrame.h:50
An ordered sequence of keyframes with STL-compliant API for finding, inserting, and erasing keyframes...
Definition: keyFrameMap.h:33
Maintains the keyframes for a spline.
Represents a spline value object.
Definition: spline.h:51
TS_API const_iterator lower_bound(const TsTime &t) const
Returns a const_iterator to the first KeyFrame with a time that is not less than t.
TS_API bool DoSidesDiffer(TsTime time) const
Returns whether the left-side value and the right-side value at the specified time are different.
TS_API bool IsTimeLooped(TsTime time) const
Is the given time in the "unrolled" region of a spline that is looping; i.e.
TS_API std::string GetTypeName() const
Returns the typename of the value type for keyframes in this spline, If no keyframes have been set,...
TS_API std::optional< TsKeyFrame > GetClosestKeyFrame(TsTime targetTime) const
Finds the keyframe closest to the given time.
TS_API void Breakdown(const std::vector< double > &times, const std::vector< TsKnotType > &types, bool flatTangents, double tangentLength, const std::vector< VtValue > &values, GfInterval *intervalAffected=nullptr, TsKeyFrameMap *keyFramesAtTimes=nullptr)
Breaks down simultaneously at several times with knot types specified for each time.
TS_API VtValue EvalDerivative(TsTime time, TsSide side=TsRight) const
Evaluates the derivative of the spline at the given time, interpolating the keyframes.
TS_API size_t count(const TsTime &t) const
Returns the number (either 0 or 1) of KeyFrames with time t.
Definition: spline.h:544
TS_API TsSpline(const std::vector< TsKeyFrame > &keyFrames, TsExtrapolationType leftExtrapolation=TsExtrapolationHeld, TsExtrapolationType rightExtrapolation=TsExtrapolationHeld, const TsLoopParams &loopParams=TsLoopParams())
Constructs a spline with the key frames keyFrames, and optionally given extrapolation and looping par...
TS_API const_iterator begin() const
Return a const_iterator pointing to the beginning of the spline.
Definition: spline.h:501
TS_API TsLoopParams GetLoopParams() const
Return an object describing all the looping parameters for this spline.
TS_API bool ClearRedundantKeyFrames(const VtValue &defaultValue=VtValue(), const GfMultiInterval &intervals=GfMultiInterval(GfInterval(-std::numeric_limits< double >::infinity(), std::numeric_limits< double >::infinity())))
Removes redundant keyframes from the spline in the specified multi-interval.
TS_API void RemoveKeyFrame(TsTime time, GfInterval *intervalAffected=nullptr)
Removes the keyframe at the given time, optionally returning the time range affected.
TS_API TfType GetType() const
Returns the TfType of the value type for keyframes in this spline.
TS_API bool IsLinear() const
Returns whether spline represents a simple linear relationship.
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.
TS_API bool CanSetKeyFrame(const TsKeyFrame &kf, std::string *reason=nullptr) const
Checks if the given keyframe is a valid candidate to set, optionally returning the reason if it canno...
TS_API void SetKeyFrame(TsKeyFrame kf, GfInterval *intervalAffected=nullptr)
Sets a keyframe, optionally returning the time range affected.
TS_API const_iterator upper_bound(const TsTime &t) const
Returns a const_iterator to the first KeyFrame with a time that is greater than t.
TS_API std::optional< TsKeyFrame > GetClosestKeyFrameAfter(TsTime targetTime) const
Finds the closest keyframe after the given time.
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.
TS_API GfInterval GetFrameRange() const
Returns the minimum and maximum keyframe frames in the spline.
TS_API VtValue EvalHeld(TsTime time, TsSide side=TsRight) const
Evaluates the value of the spline at the given time without any interpolation, as if all keyframes an...
TS_API bool KeyFrameIsInLoopedRange(const TsKeyFrame &kf)
Returns whether the given key frame is in the looped interval, but not in the master interval.
TS_API void Breakdown(const std::vector< double > &times, TsKnotType type, bool flatTangents, double tangentLength, const std::vector< VtValue > &values, GfInterval *intervalAffected=nullptr, TsKeyFrameMap *keyFramesAtTimes=nullptr)
Breaks down simultaneously at several times.
TS_API bool IsEmpty() const
Returns whether there are any keyframes.
TS_API const_iterator find(const TsTime &t) const
Returns a const_iterator to the KeyFrame at time t.
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....
TS_API const TsKeyFrameMap & GetKeyFrames() const
Returns the keyframes in this spline.
TS_API bool empty() const
Return true if this spline has no KeyFrames.
Definition: spline.h:495
TS_API const_iterator end() const
Returns a const_iterator pointing to the end of the spline.
Definition: spline.h:508
TS_API std::vector< TsKeyFrame > GetKeyFramesInMultiInterval(const GfMultiInterval &) const
Returns the keyframes contained in the given GfMultiInterval.
TS_API TsSpline(const TsKeyFrameMap &keyFrames, TsExtrapolationType leftExtrapolation=TsExtrapolationHeld, TsExtrapolationType rightExtrapolation=TsExtrapolationHeld, const TsLoopParams &loopParams=TsLoopParams())
Constructs a spline with the key frames keyFrames, and optionally given extrapolation and looping par...
TS_API const_reverse_iterator rbegin() const
Return a const_reverse_iterator pointing to the end of the spline.
Definition: spline.h:514
TS_API bool IsVaryingSignificantly() const
Like IsVarying(), but for splines of type double, allows tiny value differences.
TS_API const std::type_info & GetTypeid() const
Returns the typeid of the value type for keyframes in this spline.
TS_API bool IsKeyFrameRedundant(TsTime keyFrameTime, const VtValue &defaultValue=VtValue()) const
Returns true if the key frame at the given time is redundant.
TS_API const TsKeyFrameMap & GetRawKeyFrames() const
Returns the "raw" keyframes in this spline whether or not this spline is looping.
TS_API bool operator==(const TsSpline &rhs) const
Equality operator.
TS_API void SetExtrapolation(TsExtrapolationType left, TsExtrapolationType right)
Sets the spline's extrapolation type on each side.
TS_API bool IsKeyFrameRedundant(const TsKeyFrame &keyFrame, const VtValue &defaultValue=VtValue()) const
Returns true if the given key frame is redundant.
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 TsSpline()
Constructs a spline with no key frames and held extrapolation.
TS_API bool IsSegmentValueMonotonic(TsTime startTime, TsTime endTime) const
Returns true if the segment between the given (adjacent) key frames is monotonic (i....
TS_API bool HasRedundantKeyFrames(const VtValue &defaultValue=VtValue()) const
Returns true if any of this spline's key frames are redundant.
const_iterator iterator
Some utilities (such as TfIterator) expect a class named 'iterator'.
Definition: spline.h:475
TS_API bool operator!=(const TsSpline &rhs) const
Inequality operator.
TS_API void SwapKeyFrames(std::vector< TsKeyFrame > *swapInto)
Replaces the KeyFrames in this TsSpline with those in swapInto, and puts the KeyFrames in this TsSpli...
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 SetLoopParams(const TsLoopParams &)
Set the looping parameters for this spline.
TS_API bool IsSegmentFlat(TsTime startTime, TsTime endTime) const
Returns true if the segment between the given (adjacent) key frames is flat.
TS_API VtValue Eval(TsTime time, TsSide side=TsRight) const
Evaluates the value of the spline at the given time, interpolating the keyframes.
TS_API size_t size() const
\group Container API
Definition: spline.h:489
TS_API std::pair< TsExtrapolationType, TsExtrapolationType > GetExtrapolation() const
Returns the spline's extrapolation type on each side (first is the left side).
TS_API const_reverse_iterator rend() const
Returns a const_reverse_iterator pointing to the beginning of the spline.
Definition: spline.h:521
TS_API void Clear()
Removes all keyframes.
TS_API std::optional< TsKeyFrame > GetClosestKeyFrameBefore(TsTime targetTime) const
Finds the closest keyframe before the given time.
TS_API void Breakdown(const std::set< double > &times, TsKnotType type, bool flatTangents, double tangentLength, const VtValue &value=VtValue(), GfInterval *intervalAffected=nullptr, TsKeyFrameMap *keyFramesAtTimes=nullptr)
Breaks down simultaneously at several times.
TS_API TsSpline(const TsSpline &other)
Copy construct.
TsKeyFrameMap::const_iterator const_iterator
Our iterators are simply iterators into the contained TsKeyFrameMap We only expose const iterators be...
Definition: spline.h:469
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:147
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].