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 2024 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/splineData.h"
14 #include "pxr/base/ts/knotMap.h"
15 #include "pxr/base/ts/knot.h"
16 #include "pxr/base/ts/types.h"
18 #include "pxr/base/ts/eval.h"
19 #include "pxr/base/vt/value.h"
20 #include "pxr/base/gf/interval.h"
21 #include "pxr/base/tf/type.h"
22 
23 #include <string>
24 #include <memory>
25 #include <iosfwd>
26 
28 
29 class VtDictionary;
30 
31 
32 /// A mathematical description of a curved function from time to value.
33 ///
34 /// This class is <b>STILL IN DEVELOPMENT.</b>
35 ///
36 /// Splines are are supported only for floating-point scalar value types.
37 /// This class is non-templated, but can hold data for varying value types
38 /// (double, float, and half). All knots in a spline must have the same value
39 /// type.
40 ///
41 /// Splines are defined by <i>knots</i>. The curve passes through each knot,
42 /// and in between, the shape of the curve is controlled by <i>tangents</i>
43 /// specified at the knots.
44 ///
45 /// Splines typically have Bezier or Hermite curve segments with controllable
46 /// tangents; linear and <i>held</i> (flat) interpolation are also supported.
47 /// Outside of the time span of knots, the <i>extrapolation</i> of the curve can
48 /// be specified.
49 ///
50 /// The main service provided by splines is <i>evaluation</i>: determining the
51 /// curve's value at a given time.
52 ///
53 /// Splines are copy-on-write. Copying a spline object is cheap; the copy will
54 /// point to the same data on the heap. Copying, and then modifying one of the
55 /// copies, will incur the cost of duplicating the data, including all the
56 /// knots.
57 ///
58 class TsSpline
59 {
60 public:
61  /// \name Construction and value semantics
62  ///
63  /// This is a lightweight class that wraps a shared pointer. It is intended
64  /// to be used as a value type, and copied freely. Move semantics are not
65  /// implemented; there would be no benefit.
66  ///
67  /// @{
68 
69  /// Default constructor creates a spline without a value type. The value
70  /// type becomes established when the first knot is added.
71  TS_API
72  TsSpline();
73 
74  /// Creates a spline with a specified value type.
75  TS_API
76  TsSpline(TfType valueType);
77 
78  TS_API
79  TsSpline(const TsSpline &other);
80 
81  TS_API
82  TsSpline& operator=(const TsSpline &other);
83 
84  TS_API
85  bool operator==(const TsSpline &other) const;
86 
87  TS_API
88  bool operator!=(const TsSpline &other) const;
89 
90  /// @}
91  /// \name Value types
92  /// @{
93 
94  TS_API
95  static bool IsSupportedValueType(TfType valueType);
96 
97  TS_API
98  TfType GetValueType() const;
99 
100  template <typename T>
101  bool IsHolding() const;
102 
103  TS_API
104  void SetTimeValued(bool timeValued);
105 
106  TS_API
107  bool IsTimeValued() const;
108 
109  /// @}
110  /// \name Curve types
111  /// @{
112 
113  TS_API
114  void SetCurveType(TsCurveType curveType);
115 
116  TS_API
117  TsCurveType GetCurveType() const;
118 
119  /// @}
120  /// \name Extrapolation
121  /// @{
122 
123  TS_API
124  void SetPreExtrapolation(
125  const TsExtrapolation &extrap);
126 
127  TS_API
129 
130  TS_API
132  const TsExtrapolation &extrap);
133 
134  TS_API
136 
137  /// @}
138  /// \name Inner loops
139  ///
140  /// Loop params are only valid when all of the following are true:
141  ///
142  /// - protoEnd > protoStart.
143  /// - At least one of numPreLoops or numPostLoops is nonzero and positive.
144  /// - There is a knot at protoStart.
145  ///
146  /// Any loop params may be set, and will be stored. Whenever the above
147  /// conditions are not met, the stored params will be ignored.
148  ///
149  /// To determine if loop params are currently valid, call HasInnerLoops.
150  ///
151  /// To disable inner loops, call
152  /// <code>SetInnerLoopParams(TsLoopParams())</code>.
153  ///
154  /// @{
155 
156  TS_API
157  void SetInnerLoopParams(
158  const TsLoopParams &params);
159 
160  TS_API
162 
163  /// @}
164  /// \name Knots
165  /// @{
166 
167  TS_API
168  void SetKnots(
169  const TsKnotMap &knots);
170 
171  TS_API
172  bool CanSetKnot(
173  const TsKnot &knot,
174  std::string *reasonOut = nullptr) const;
175 
176  /// <b>Incompletely implemented</b>; \p affectedIntervalOut is not yet
177  /// populated.
178  TS_API
179  bool SetKnot(
180  const TsKnot &knot,
181  GfInterval *affectedIntervalOut = nullptr);
182 
183  /// Returns the spline's knots. These are the original knots; if inner or
184  /// extrapolating loops are present, this set of knots does not reflect
185  /// that.
186  TS_API
187  TsKnotMap GetKnots() const;
188 
189  /// Retrieves a copy of the knot at the specified time, if one exists. This
190  /// must be an original knot, not a knot that is echoed due to looping.
191  /// Returns true on success, false if there is no such knot.
192  TS_API
193  bool GetKnot(
194  TsTime time,
195  TsKnot *knotOut) const;
196 
197  /// @}
198  /// \name Removing knots
199  /// @{
200 
201  TS_API
202  void ClearKnots();
203 
204  /// <b>Incompletely implemented</b>; \p affectedIntervalOut is not yet
205  /// populated.
206  TS_API
207  void RemoveKnot(
208  TsTime time,
209  GfInterval *affectedIntervalOut = nullptr);
210 
211  /// <b>Not yet implemented.</b>
212  TS_API
213  bool ClearRedundantKnots(
214  VtValue defaultValue = VtValue(),
215  const GfInterval &interval = GfInterval::GetFullInterval());
216 
217  /// @}
218  /// \name Loop baking
219  /// @{
220 
221  /// <b>Not yet implemented.</b>
222  TS_API
223  bool BakeLoops(
224  const GfInterval &interval);
225 
226  /// <b>Not yet implemented.</b>
227  //
228  // Result cached
229  TS_API
230  const TsKnotMap& GetKnotsWithInnerLoopsBaked() const;
231 
232  /// <b>Not yet implemented.</b>
233  //
234  // Bakes inner loops (finite) and extrapolating loops (infinite)
235  // Result cached, but only for last specified interval
236  TS_API
238  const GfInterval &interval) const;
239 
240  /// @}
241  /// \name Splitting
242  /// @{
243 
244  /// <b>Not yet implemented.</b>
245  ///
246  /// Adds a knot at the specified time. The new knot is arranged so that the
247  /// shape of the curve is as unchanged as possible.
248  TS_API
249  bool Split(
250  TsTime time,
251  GfInterval *affectedIntervalOut = nullptr);
252 
253  /// @}
254  /// \name Anti-regression
255  ///
256  /// See \ref page_ts_regression for a general introduction to regression and
257  /// anti-regression.
258  ///
259  /// \sa TsAntiRegressionAuthoringSelector
260  /// \sa TsRegressionPreventer
261  /// @{
262 
263  /// Returns the current effective anti-regression authoring mode. This may
264  /// come from the overall default of Keep Ratio; the build-configured
265  /// default defined by \c PXR_TS_DEFAULT_ANTI_REGRESSION_AUTHORING_MODE; or
266  /// a TsAntiRegressionAuthoringSelector.
267  TS_API
269 
270  /// Returns whether this spline has any tangents long enough to cause
271  /// regression; or, if the current authoring mode is Contain, whether this
272  /// spline has any tangents that exceed their segment interval.
273  TS_API
274  bool HasRegressiveTangents() const;
275 
276  /// Shorten any regressive tangents; or, if the current authoring mode is
277  /// Contain, any tangents that exceed their segment interval. Return
278  /// whether anything was changed.
279  TS_API
281 
282  /// @}
283  /// \name Evaluation
284  /// @{
285  ///
286  /// In all of these templated methods, the T parameter may be the value type
287  /// of the spline (double/float/GfHalf), or VtValue.
288 
289  template <typename T>
290  bool Eval(
291  TsTime time,
292  T *valueOut) const;
293 
294  template <typename T>
295  bool EvalPreValue(
296  TsTime time,
297  T *valueOut) const;
298 
299  template <typename T>
300  bool EvalDerivative(
301  TsTime time,
302  T *valueOut) const;
303 
304  template <typename T>
305  bool EvalPreDerivative(
306  TsTime time,
307  T *valueOut) const;
308 
309  template <typename T>
310  bool EvalHeld(
311  TsTime time,
312  T *valueOut) const;
313 
314  template <typename T>
315  bool EvalPreValueHeld(
316  TsTime time,
317  T *valueOut) const;
318 
319  TS_API
320  bool DoSidesDiffer(
321  TsTime time) const;
322 
323  /// \brief Evaluates the value of the TsSpline over the given time interval,
324  /// typically for drawing.
325  ///
326  /// \c Sample creates a piecewise linear approximation of the spline curve.
327  /// When the returned samples are scaled by \e timeScale and \e valueScale
328  /// and linearly interpolated, the reconstructed curve will nowhere have an
329  /// error greater than \e tolerance.
330  ///
331  /// The values of \e timeScale and \e valueScale are typically chosen to
332  /// scale the spline's units to pixels and then \e tolerance represents
333  /// the allowed deviation in pixel space from a theoretical exact answer.
334  ///
335  /// \c timeInterval must not be empty and \c timeScale, \c valueScale, and
336  /// \c tolerance must all be greater than 0.0. If any of these conditions
337  /// are not met, \c Sample returns false and \c *splineSamples is unchanged.
338  /// Otherwise, true is returned and \c splineSamples is populated.
339  template <typename Vertex>
340  bool
342  const GfInterval& timeInterval,
343  double timeScale,
344  double valueScale,
345  double tolerance,
346  TsSplineSamples<Vertex>* splineSamples) const
347  {
348  return _Sample(timeInterval, timeScale, valueScale, tolerance,
349  splineSamples);
350  }
351 
352  /// \overload
353  /// When passed a \c TsSplineSamplesWithSources<Vertex> class, the returned
354  /// information contains a \c TsSplineSampleSource value for each
355  /// polyline. The \c TsSplineSampleSource indicates the source region
356  /// (extrapolation, looping, normal interpolation, etc.) of the spline
357  /// generated that polyline.
358  template <typename Vertex>
359  bool
361  const GfInterval& timeInterval,
362  double timeScale,
363  double valueScale,
364  double tolerance,
365  TsSplineSamplesWithSources<Vertex>* splineSamples) const
366  {
367  return _Sample(timeInterval, timeScale, valueScale, tolerance,
368  splineSamples);
369  }
370 
371  /// @}
372  /// \name Whole-spline queries
373  /// @{
374 
375  TS_API
376  bool IsEmpty() const;
377 
378  TS_API
379  bool HasValueBlocks() const;
380 
381  /// <b>Not yet implemented.</b>
382  TS_API
383  bool IsVarying() const;
384 
385  /// Convenience for HasInnerLoops() || HasExtrapolatingLoops().
386  TS_API
387  bool HasLoops() const;
388 
389  TS_API
390  bool HasInnerLoops() const;
391 
392  TS_API
393  bool HasExtrapolatingLoops() const;
394 
395  /// <b>Not yet implemented.</b>
396  TS_API
397  bool IsLinear() const;
398 
399  /// <b>Not yet implemented.</b>
400  TS_API
401  bool IsC0Continuous() const;
402 
403  /// <b>Not yet implemented.</b>
404  TS_API
405  bool IsG1Continuous() const;
406 
407  /// <b>Not yet implemented.</b>
408  TS_API
409  bool IsC1Continuous() const;
410 
411  /// <b>Not yet implemented.</b>
412  TS_API
413  bool GetValueRange(
414  const GfInterval &timeSpan,
415  std::pair<VtValue, VtValue> *rangeOut) const;
416 
417  /// <b>Not yet implemented.</b>
418  template <typename T>
419  bool GetValueRange(
420  const GfInterval &timeSpan,
421  std::pair<T, T> *rangeOut) const;
422 
423  /// @}
424  /// \name Within-spline queries
425  /// @{
426 
427  TS_API
428  bool HasValueBlockAtTime(
429  TsTime time) const;
430 
431  /// <b>Not yet implemented.</b>
432  TS_API
433  bool IsSegmentFlat(
434  TsTime startTime) const;
435 
436  /// <b>Not yet implemented.</b>
437  TS_API
438  bool IsSegmentMonotonic(
439  TsTime startTime) const;
440 
441  /// <b>Not yet implemented.</b>
442  TS_API
443  bool IsKnotRedundant(
444  TsTime time,
445  VtValue defaultValue = VtValue()) const;
446 
447  /// @}
448 
449 public:
450  // Hash function. For now this is cheap, and only hashes by data pointer.
451  // If there are two identical but independent splines, they will hash
452  // unequal.
453  template <typename HashState>
454  friend void TfHashAppend(
455  HashState &h,
456  const TsSpline &spline)
457  {
458  h.Append(spline._data.get());
459  }
460 
461 private:
462  friend class TsRegressionPreventer;
463  void _SetKnotUnchecked(const TsKnot & knot);
464 
465  template <typename SampleHolder>
466  bool _Sample(
467  const GfInterval& timeInterval,
468  double timeScale,
469  double valueScale,
470  double tolerance,
471  SampleHolder* splineSamples) const;
472 
473  // External helpers provide direct data access for Ts implementation.
474  friend Ts_SplineData* Ts_GetSplineData(TsSpline &spline);
475  friend const Ts_SplineData* Ts_GetSplineData(const TsSpline &spline);
476 
477  friend struct Ts_BinaryDataAccess;
478  friend struct Ts_SplineOffsetAccess;
479 
480 private:
481  // Get data to read from. Will be either actual data or default data.
482  TS_API
483  const Ts_SplineData* _GetData() const;
484 
485  // Ensure we have our own independent data, in preparation for writing. If
486  // a value type is passed, and we don't yet have typed data, ensure we have
487  // data of the specified type.
488  void _PrepareForWrite(TfType valueType = TfType());
489 
490  template <typename T>
491  bool _Eval(
492  TsTime time,
493  T *valueOut,
494  Ts_EvalAspect aspect,
495  Ts_EvalLocation location) const;
496 
497 private:
498  // Our parameter data. Copy-on-write. Null only if we are in the default
499  // state, with no knots, and all overall parameters set to defaults. To
500  // deal with the possibility of null data, call _GetData for reading, and
501  // _PrepareForWrite before writing.
502  std::shared_ptr<Ts_SplineData> _data;
503 };
504 
505 /// Output a text representation of a spline to a stream.
506 TS_API
507 std::ostream& operator<<(std::ostream& out, const TsSpline &spline);
508 
509 // XXX: This should not be necessary. All it does is call std::swap. This is
510 // here as a workaround for a downstream library that tries to call swap on
511 // splines, with a "using namespace std" that doesn't appear to work when pxr
512 // namespaces are in use.
513 TS_API
514 void swap(TsSpline &lhs, TsSpline &rhs);
515 
516 // For applying layer offsets.
518 {
519  TS_API
520  static void ApplyOffsetAndScale(
521  TsSpline *spline,
522  const TsTime offset,
523  const double scale);
524 };
525 
526 
527 ////////////////////////////////////////////////////////////////////////////////
528 // TEMPLATE IMPLEMENTATIONS
529 
530 template <typename T>
532 {
533  if constexpr (!Ts_IsSupportedValueType<T>::value)
534  {
535  return false;
536  }
537 
538  return GetValueType() == Ts_GetType<T>();
539 }
540 
541 template <typename T>
542 bool TsSpline::_Eval(
543  const TsTime time,
544  T* const valueOut,
545  const Ts_EvalAspect aspect,
546  const Ts_EvalLocation location) const
547 {
548  const std::optional<double> result =
549  Ts_Eval(_GetData(), time, aspect, location);
550 
551  if (!result)
552  {
553  return false;
554  }
555 
556  *valueOut = T(*result);
557  return true;
558 }
559 
560 // Implement a special case that will ensure the contents of the VtValue output
561 // variable contain a value of the same type (double, float, or GfHalf) as the
562 // spline.
563 template <>
564 TS_API
565 bool TsSpline::_Eval(
566  const TsTime time,
567  VtValue* const valueOut,
568  const Ts_EvalAspect aspect,
569  const Ts_EvalLocation location) const;
570 
571 template <typename T>
572 bool TsSpline::Eval(const TsTime time, T* const valueOut) const
573 {
574  return _Eval(time, valueOut, Ts_EvalValue, Ts_EvalAtTime);
575 }
576 
577 template <typename T>
578 bool TsSpline::EvalPreValue(const TsTime time, T* const valueOut) const
579 {
580  return _Eval(time, valueOut, Ts_EvalValue, Ts_EvalPre);
581 }
582 
583 template <typename T>
584 bool TsSpline::EvalDerivative(const TsTime time, T* const valueOut) const
585 {
586  return _Eval(time, valueOut, Ts_EvalDerivative, Ts_EvalAtTime);
587 }
588 
589 template <typename T>
590 bool TsSpline::EvalPreDerivative(const TsTime time, T* const valueOut) const
591 {
592  return _Eval(time, valueOut, Ts_EvalDerivative, Ts_EvalPre);
593 }
594 
595 template <typename T>
596 bool TsSpline::EvalHeld(const TsTime time, T* const valueOut) const
597 {
598  return _Eval(time, valueOut, Ts_EvalHeldValue, Ts_EvalAtTime);
599 }
600 
601 template <typename T>
602 bool TsSpline::EvalPreValueHeld(const TsTime time, T* const valueOut) const
603 {
604  return _Eval(time, valueOut, Ts_EvalHeldValue, Ts_EvalPre);
605 }
606 
607 
609 
610 #endif
bool Sample(const GfInterval &timeInterval, double timeScale, double valueScale, double tolerance, TsSplineSamplesWithSources< Vertex > *splineSamples) const
Definition: spline.h:360
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
Definition: assetInfo.h:57
TsAntiRegressionMode
Definition: types.h:272
TS_API bool IsC0Continuous() const
Not yet implemented.
bool EvalHeld(TsTime time, T *valueOut) const
Evaluates the value of the TsSpline over the given time interval, typically for drawing.
Definition: spline.h:596
TsSplineSamplesWithSources<Vertex> is a TsSplineSamples<Vertex> that also includes source information...
Definition: types.h:244
bool Eval(TsTime time, T *valueOut) const
Evaluates the value of the TsSpline over the given time interval, typically for drawing.
Definition: spline.h:572
friend Ts_SplineData * Ts_GetSplineData(TsSpline &spline)
static TS_API bool IsSupportedValueType(TfType valueType)
TS_API void ClearKnots()
TS_API TsExtrapolation GetPreExtrapolation() const
Ts_EvalLocation
Definition: eval.h:29
TS_API bool IsSegmentFlat(TsTime startTime) const
Not yet implemented.
GT_API const UT_StringHolder time
TS_API bool IsEmpty() const
Not yet implemented.
TS_API bool ClearRedundantKnots(VtValue defaultValue=VtValue(), const GfInterval &interval=GfInterval::GetFullInterval())
Not yet implemented.
TS_API bool BakeLoops(const GfInterval &interval)
Not yet implemented.
static TS_API TsAntiRegressionMode GetAntiRegressionAuthoringMode()
TS_API TsCurveType GetCurveType() const
TS_API bool HasRegressiveTangents() const
TS_API bool SetKnot(const TsKnot &knot, GfInterval *affectedIntervalOut=nullptr)
TS_API const TsKnotMap & GetKnotsWithLoopsBaked(const GfInterval &interval) const
Not yet implemented.
TS_API TfType GetValueType() const
TS_API bool DoSidesDiffer(TsTime time) const
Evaluates the value of the TsSpline over the given time interval, typically for drawing.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat< T > spline(const Quat< T > &q0, const Quat< T > &q1, const Quat< T > &q2, const Quat< T > &q3, T t) IMATH_NOEXCEPT
Definition: ImathQuat.h:576
static GfInterval GetFullInterval()
Returns the full interval (-inf, inf).
Definition: interval.h:325
TS_API void SetKnots(const TsKnotMap &knots)
**But if you need a result
Definition: thread.h:622
friend void TfHashAppend(HashState &h, const TsSpline &spline)
Definition: spline.h:454
TS_API bool IsSegmentMonotonic(TsTime startTime) const
Not yet implemented.
TS_API bool IsC1Continuous() const
Not yet implemented.
GLenum const GLfloat * params
Definition: glcorearb.h:105
TS_API TsExtrapolation GetPostExtrapolation() const
TS_API bool AdjustRegressiveTangents()
TS_API bool GetValueRange(const GfInterval &timeSpan, std::pair< VtValue, VtValue > *rangeOut) const
Not yet implemented.
static TS_API void ApplyOffsetAndScale(TsSpline *spline, const TsTime offset, const double scale)
Ts_EvalAspect
Definition: eval.h:22
TS_API TsKnotMap GetKnots() const
TS_API bool GetKnot(TsTime time, TsKnot *knotOut) const
GA_API const UT_StringHolder scale
TS_API void SetInnerLoopParams(const TsLoopParams &params)
GLintptr offset
Definition: glcorearb.h:665
TS_API void SetCurveType(TsCurveType curveType)
TS_API bool IsG1Continuous() const
Not yet implemented.
TS_API void SetPostExtrapolation(const TsExtrapolation &extrap)
TsCurveType
Definition: types.h:92
TS_API bool HasExtrapolatingLoops() const
Not yet implemented.
bool IsHolding() const
Definition: spline.h:531
bool EvalDerivative(TsTime time, T *valueOut) const
Evaluates the value of the TsSpline over the given time interval, typically for drawing.
Definition: spline.h:584
TS_API bool HasLoops() const
Convenience for HasInnerLoops() || HasExtrapolatingLoops().
GLint location
Definition: glcorearb.h:805
TS_API bool operator!=(const TsSpline &other) const
TS_API std::optional< double > Ts_Eval(const Ts_SplineData *data, TsTime time, Ts_EvalAspect aspect, Ts_EvalLocation location)
TS_API bool IsTimeValued() const
TS_API TsSpline()
#define TS_API
Definition: api.h:24
TS_API bool HasValueBlockAtTime(TsTime time) const
Not yet implemented.
Definition: knot.h:39
TS_API bool IsKnotRedundant(TsTime time, VtValue defaultValue=VtValue()) const
Not yet implemented.
TS_API bool operator==(const TsSpline &other) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
TS_API const TsKnotMap & GetKnotsWithInnerLoopsBaked() const
Not yet implemented.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
TS_API void RemoveKnot(TsTime time, GfInterval *affectedIntervalOut=nullptr)
TS_API TsLoopParams GetInnerLoopParams() const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
TS_API bool IsLinear() const
Not yet implemented.
TS_API bool CanSetKnot(const TsKnot &knot, std::string *reasonOut=nullptr) const
Definition: type.h:47
bool EvalPreValue(TsTime time, T *valueOut) const
Evaluates the value of the TsSpline over the given time interval, typically for drawing.
Definition: spline.h:578
TS_API std::ostream & operator<<(std::ostream &out, const TsSpline &spline)
Output a text representation of a spline to a stream.
TS_API bool HasInnerLoops() const
Not yet implemented.
TS_API bool HasValueBlocks() const
Not yet implemented.
TS_API bool IsVarying() const
Not yet implemented.
bool EvalPreValueHeld(TsTime time, T *valueOut) const
Evaluates the value of the TsSpline over the given time interval, typically for drawing.
Definition: spline.h:602
TsSplineSamples<Vertex> holds a collection of piecewise linear polylines that approximate a TsSpline...
Definition: types.h:221
TS_API bool Split(TsTime time, GfInterval *affectedIntervalOut=nullptr)
TS_API void SetTimeValued(bool timeValued)
bool EvalPreDerivative(TsTime time, T *valueOut) const
Evaluates the value of the TsSpline over the given time interval, typically for drawing.
Definition: spline.h:590
bool Sample(const GfInterval &timeInterval, double timeScale, double valueScale, double tolerance, TsSplineSamples< Vertex > *splineSamples) const
Evaluates the value of the TsSpline over the given time interval, typically for drawing.
Definition: spline.h:341
Definition: value.h:146
TS_API TsSpline & operator=(const TsSpline &other)
TS_API void SetPreExtrapolation(const TsExtrapolation &extrap)