HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
segment.h
Go to the documentation of this file.
1 //
2 // Copyright 2025 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_SEGMENT_H
9 #define PXR_BASE_TS_SEGMENT_H
10 
11 #include "pxr/pxr.h"
12 
13 #include "pxr/base/ts/api.h"
14 #include "pxr/base/ts/types.h"
15 
16 #include "pxr/base/gf/vec2d.h"
17 
19 
20 /// Ts_SegmentInterp declares the type of interpolation that should be used
21 /// between the end-points of a segment.
22 //
23 /// It is a scoped enum so the use of the Ts_SegmentInterp:: prefix is required.
24 enum class Ts_SegmentInterp
25 {
26  ValueBlock, //< This segment explicitly has no value
27  Held, //< The value is always the starting value
28  Linear, //< Interpolate linearly from start to end
29  Bezier, //< The segment uses Bezier interpolation
30  Hermite, //< The segment uses Hermite interpolation
31  PreExtrap, //< Linear extrapolation from -infinity to
32  //< the end value with a fixed slope
33  PostExtrap //< Linear extrapolation to +infinity from
34  //< the start value with a fixed slope
35 };
36 
37 /// Ts_Segment represents one section of a spline. It generally contains the
38 /// "post" side values of one knot (time, value, tangent, and interpolation) and
39 /// the "pre" side of the next knot (preValue and tangent). There are special
40 /// case interpolation types for pre- and post-extrapolation and the curve
41 /// interpolation of \c TsKnot has been split into separate Bezier and Hermite
42 /// values.
43 ///
44 /// The data is stored as 4 GfVec2d values that represent (time, value) points
45 /// that are the knot points and the tangent end points. Note that the tangents
46 /// are stored as their end points rather than as width and slope as they are in
47 /// the knots. Also note that held interpolation segments still store the value
48 /// of the post-side knot even though that value is not used for segment
49 /// interpolation. This allows the knots to be reconstructed from the segment
50 /// data.
51 ///
52 /// If the interpolation is PreExtrap or PostExtrap then the starting or ending
53 /// point (respectively) contains (+/- infinity, slope) rather than (time,
54 /// value). The straight line is extrapolated to infinity from the other end
55 /// point of the segment with the given slope.
56 struct Ts_Segment
57 {
63 
64  /// Set interp from a TsInterpMode and TsCurveType.
65  void SetInterp(TsInterpMode interpMode, TsCurveType curveType);
66 
67  /// Add the (timeDelta, valueDelta) contained in the \c GfVec2d argument to
68  /// the segment's time and value.
70  {
71  p0 += delta;
72  t0 += delta;
73  t1 += delta;
74  p1 += delta;
75 
76  return *this;
77  }
78 
79  /// Add the timeDelta argument to the segment's time
80  Ts_Segment& operator +=(const double timeDelta)
81  {
82  p0[0] += timeDelta;
83  t0[0] += timeDelta;
84  t1[0] += timeDelta;
85  p1[0] += timeDelta;
86 
87  return *this;
88  }
89 
90  /// Subtract the (timeDelta, valueDelta) contained in the \c GfVec2d
91  /// argument from the segment's time and value.
93  {
94  p0 -= delta;
95  t0 -= delta;
96  t1 -= delta;
97  p1 -= delta;
98 
99  return *this;
100  }
101 
102  /// Subtract the timeDelta argument from the segment's time
103  Ts_Segment& operator -=(const double timeDelta)
104  {
105  p0[0] -= timeDelta;
106  t0[0] -= timeDelta;
107  t1[0] -= timeDelta;
108  p1[0] -= timeDelta;
109 
110  return *this;
111  }
112 
113  /// Addition operator.
114  template <typename T>
115  Ts_Segment operator +(const T& delta) const
116  {
117  Ts_Segment result = *this;
118  result += delta;
119  return result;
120  }
121 
122  // Subtraction operator
123  template <typename T>
124  Ts_Segment operator -(const T& delta) const
125  {
126  Ts_Segment result = *this;
127  result -= delta;
128  return result;
129  }
130 
131  // Unary negation operator - negates the times, not the values.
133  {
134  Ts_Segment result = *this;
135  result.p0[0] = -result.p0[0];
136  result.t0[0] = -result.t0[0];
137  result.t1[0] = -result.t1[0];
138  result.p1[0] = -result.p1[0];
139 
140  // Now swap the points back into the correct order (p0 always has the
141  // smallest time value).
142  using std::swap;
143  swap(result.p0, result.p1);
144  swap(result.t0, result.t1);
145 
146  return result;
147  }
148 
149  /// Compare for equivalence
150  bool operator ==(const Ts_Segment& rhs) const
151  {
152  return (p0 == rhs.p0 &&
153  t0 == rhs.t0 &&
154  t1 == rhs.t1 &&
155  p1 == rhs.p1 &&
156  interp == rhs.interp);
157  }
158 
159  /// Not equivalent
160  bool operator !=(const Ts_Segment& rhs) const
161  {
162  return !(*this == rhs);
163  }
164 
165  bool IsClose(const Ts_Segment& other, const double tolerance) const
166  {
167  return (interp == other.interp &&
168  GfIsClose(p0, other.p0, tolerance) &&
169  GfIsClose(t0, other.t0, tolerance) &&
170  GfIsClose(t1, other.t1, tolerance) &&
171  GfIsClose(p1, other.p1, tolerance));
172  }
173 
174  /// Compute dv/dt at the value u in the interval [0..1].
175  /// Note: This currently only supports u == 0.0 or u == 1.0.
176  TS_API
177  double _ComputeDerivative(double u) const;
178 };
179 
180 // For testing purposes.
181 TS_API
182 std::ostream& operator <<(std::ostream&, const Ts_SegmentInterp);
183 TS_API
184 std::ostream& operator <<(std::ostream&, const Ts_Segment&);
185 
187 
188 #endif
TS_API std::ostream & operator<<(std::ostream &, const Ts_SegmentInterp)
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
Definition: UT_ArraySet.h:1699
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
TS_API double _ComputeDerivative(double u) const
void swap(T &lhs, T &rhs)
Definition: pugixml.cpp:7440
bool IsClose(const Ts_Segment &other, const double tolerance) const
Definition: segment.h:165
**But if you need a result
Definition: thread.h:622
GfVec2d p1
Definition: segment.h:61
GfVec2d p0
Definition: segment.h:58
bool operator==(const Ts_Segment &rhs) const
Compare for equivalence.
Definition: segment.h:150
Definition: vec2d.h:45
Ts_Segment & operator+=(const GfVec2d &delta)
Definition: segment.h:69
void SetInterp(TsInterpMode interpMode, TsCurveType curveType)
Set interp from a TsInterpMode and TsCurveType.
TsCurveType
Definition: types.h:92
GfVec2d t0
Definition: segment.h:59
#define TS_API
Definition: api.h:24
Ts_SegmentInterp
It is a scoped enum so the use of the Ts_SegmentInterp:: prefix is required.
Definition: segment.h:24
GfVec2d t1
Definition: segment.h:60
Ts_Segment operator+(const T &delta) const
Addition operator.
Definition: segment.h:115
Ts_SegmentInterp interp
Definition: segment.h:62
bool GfIsClose(GfColor const &c1, GfColor const &c2, double tolerance)
Definition: color.h:114
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
Ts_Segment & operator-=(const GfVec2d &delta)
Definition: segment.h:92
bool operator!=(const Ts_Segment &rhs) const
Not equivalent.
Definition: segment.h:160
TsInterpMode
Definition: types.h:82
Ts_Segment operator-() const
Definition: segment.h:132