8 #ifndef PXR_BASE_TS_SPLINE_DATA_H
9 #define PXR_BASE_TS_SPLINE_DATA_H
22 #include <unordered_map>
110 size_t *firstProtoIndexOut =
nullptr)
const;
177 template <
typename T>
228 double scale)
override;
237 std::vector<Ts_TypedKnotData<T>>
knots;
250 template <
typename T>
254 template <
typename T>
262 template <
typename T>
270 return Ts_GetType<T>();
273 template <
typename T>
279 template <
typename T>
286 template <
typename T>
312 return knots == typedOther->
knots;
315 template <
typename T>
319 times.reserve(count);
320 knots.reserve(count);
323 template <
typename T>
331 times.push_back(knotData->
time);
332 knots.push_back(*typedKnotData);
334 if (!customDataIn.
empty())
336 customData[knotData->
time] = customDataIn;
379 template <
typename T>
389 std::lower_bound(times.begin(), times.end(), knotData->
time);
392 const bool overwrite =
393 (it != times.end() && *it == knotData->
time);
398 times[idx] = knotData->
time;
399 knots[idx] = *typedKnotData;
403 times.insert(it, knotData->
time);
404 knots.insert(knots.begin() + idx, *typedKnotData);
408 if (!customDataIn.
empty())
410 customData[knotData->
time] = customDataIn;
416 template <
typename T>
422 if constexpr(std::is_same_v<T, double>) {
423 return SetKnot(knotData, customDataIn);
431 static_cast<const Ts_KnotData&>(*knotData);
441 return std::max(
T(
v), std::numeric_limits<T>::lowest());
446 typedData.
value = _Clamp_cast(knotData->
value);
453 auto _ConvertTangent =
454 [&_Clamp_cast](
double slope,
double*
width) ->
T
456 T typedSlope =
T(slope);
468 typedSlope = _Clamp_cast(slope);
471 *
width = height / typedSlope;
481 return SetKnot(&typedData, customDataIn);
484 template <
typename T>
487 const size_t index)
const
492 template <
typename T>
495 const TsTime
time)
const
497 const auto it = std::lower_bound(times.begin(), times.end(),
time);
498 if (it == times.end() || *it !=
time)
503 const auto knotIt = knots.begin() + (it - times.begin());
507 template <
typename T>
512 return &(knots[
index]);
515 template <
typename T>
518 const size_t index)
const
520 return &(knots[
index]);
524 template <
typename T>
527 const size_t index)
const
534 static_cast<Ts_KnotData&
>(out) = static_cast<const Ts_KnotData&>(in);
546 template <
typename T>
549 const size_t index)
const
552 return typedData.
value;
556 template <
typename T>
559 const size_t index)
const
565 template <
typename T>
573 template <
typename T>
577 const auto it = std::lower_bound(times.begin(), times.end(),
time);
578 if (it == times.end() || *it !=
time)
584 const size_t idx = it - times.begin();
586 customData.erase(time);
587 knots.erase(knots.begin() + idx);
591 UpdateKnotTangentsAtIndex(idx - 1);
593 if (idx < times.size()) {
594 UpdateKnotTangentsAtIndex(idx);
598 template <
typename T>
599 static void _ApplyOffsetAndScaleToKnot(
605 TF_VERIFY(scale > 0);
619 template <
typename T>
627 "collapsing/reversing time and spline representation "
641 preExtrapolation.slope /=
scale;
645 postExtrapolation.slope /=
scale;
649 if (loopParams.protoEnd > loopParams.protoStart)
652 loopParams.protoStart = loopParams.protoStart * scale +
offset;
653 loopParams.protoEnd = loopParams.protoEnd * scale +
offset;
657 for (TsTime &
time : times) {
668 _ApplyOffsetAndScaleToKnot(&knotData, offset, scale);
672 static_cast<T>(knotData.value * scale +
offset);
674 static_cast<T>(knotData.preValue * scale +
offset);
680 _ApplyOffsetAndScaleToKnot(&knotData, offset, scale);
685 if (!customData.empty())
687 std::unordered_map<TsTime, VtDictionary> newCustomData;
688 for (
const auto &mapPair : customData) {
689 newCustomData[mapPair.first * scale +
offset] = mapPair.second;
691 customData.swap(newCustomData);
695 template <
typename T>
720 template <
typename T>
722 const TsTime
time)
const
732 std::lower_bound(times.begin(), times.end(),
time);
736 if (lbIt == times.end())
745 const auto knotIt = knots.begin() + (lbIt - times.begin());
751 if (lbIt == times.begin())
758 const auto knotIt = knots.begin() + (lbIt - times.begin());
762 template <
typename T>
766 if (!TF_VERIFY(index < knots.size(),
767 "Knot index (%zd) out of range [0 .. %zd)",
768 index, knots.size()))
782 template <
typename T>
790 template <
typename T>
void PushKnot(const Ts_KnotData *knotData, const VtDictionary &customData) override
std::vector< Ts_TypedKnotData< T > > knots
std::unordered_map< TsTime, VtDictionary > customData
Ts_KnotData * CloneKnotAtIndex(size_t index) const override
bool operator==(const Ts_SplineData &other) const override
virtual Ts_KnotData * CloneKnotAtIndex(size_t index) const =0
GT_API const UT_StringHolder time
virtual Ts_SplineData * Clone() const =0
virtual bool operator==(const Ts_SplineData &other) const =0
#define PXR_NAMESPACE_OPEN_SCOPE
bool HasValueBlockAtTime(TsTime time) const override
TsTime GetPreExtrapTime() const
void RemoveKnotAtTime(TsTime time) override
virtual bool HasValueBlocks() const =0
virtual void ClearKnots()=0
virtual double GetKnotValueAsDouble(size_t index) const =0
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
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
double GetKnotPreValueAsDouble(size_t index) const override
TsExtrapolation postExtrapolation
bool HasInnerLoops(size_t *firstProtoIndexOut=nullptr) const
constexpr auto in(type t, int set) -> bool
virtual double GetKnotPreValueAsDouble(size_t index) const =0
bool UpdateKnotTangentsAtIndex(size_t index) override
std::vector< TsTime > times
GA_API const UT_StringHolder scale
virtual size_t SetKnot(const Ts_KnotData *knotData, const VtDictionary &customData)=0
GLint GLsizei GLsizei height
double GetKnotValueAsDouble(size_t index) const override
virtual size_t SetKnotFromDouble(const Ts_TypedKnotData< double > *knotData, const VtDictionary &customData)=0
TsExtrapolation preExtrapolation
virtual Ts_KnotData * GetKnotPtrAtIndex(size_t index)=0
size_t GetKnotStructSize() const override
virtual bool HasValueBlockAtTime(TsTime time) const =0
double GetPreExtrapValue() const
virtual Ts_KnotData * CloneKnotAtTime(TsTime time) const =0
Ts_SplineData * Clone() const override
TfType GetValueType() const override
Ts_TypedKnotData< double > GetKnotDataAsDouble(size_t index) const override
virtual bool UpdateKnotTangentsAtIndex(size_t index)=0
Ts_KnotData * CloneKnotAtTime(TsTime time) const override
VT_API bool empty() const
true if the VtDictionary's size is 0.
void ClearKnots() override
Ts_TypedSplineData< T > * Ts_GetTypedSplineData(TsSpline &spline)
void ReserveForKnotCount(size_t count) override
TsTime GetPostExtrapTime() const
double GetPostExtrapValue() const
size_t SetKnot(const Ts_KnotData *knotData, const VtDictionary &customData) override
bool Ts_IsFinite(T value)
virtual Ts_TypedKnotData< double > GetKnotDataAsDouble(size_t index) const =0
virtual void PushKnot(const Ts_KnotData *knotData, const VtDictionary &customData)=0
virtual TfType GetValueType() const =0
bool HasValueBlocks() const override
virtual void ApplyOffsetAndScale(TsTime offset, double scale)=0
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
#define PXR_NAMESPACE_CLOSE_SCOPE
void ApplyOffsetAndScale(TsTime offset, double scale) override
Ts_KnotData * GetKnotPtrAtIndex(size_t index) override
static Ts_SplineData * Create(TfType valueType, const Ts_SplineData *overallParamSource=nullptr)
virtual void RemoveKnotAtTime(TsTime time)=0
virtual void ReserveForKnotCount(size_t count)=0
TS_API bool UpdateTangents(const Ts_TypedKnotData< T > *prevData, const Ts_TypedKnotData< T > *nextData, const TsCurveType curveType)
size_t SetKnotFromDouble(const Ts_TypedKnotData< double > *knotData, const VtDictionary &customData) override
Ts_SplineData * Ts_GetSplineData(TsSpline &spline)
virtual size_t GetKnotStructSize() const =0