Loading...
Searching...
No Matches
tsTest_SplineData.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_TS_TEST_SPLINE_DATA_H
9#define PXR_BASE_TS_TS_TEST_SPLINE_DATA_H
10
11#include "pxr/pxr.h"
12#include "pxr/base/ts/api.h"
13
14#include <string>
15#include <set>
16
17PXR_NAMESPACE_OPEN_SCOPE
18
19// A generic way of encoding spline control parameters. Allows us to pass the
20// same data to different backends (Ts, mayapy, etc) for evaluation.
21//
22class TsTest_SplineData
23{
24public:
25 // Interpolation method for a spline segment.
26 enum InterpMethod
27 {
28 InterpHeld,
29 InterpLinear,
30 InterpCurve
31 };
32
33 // Extrapolation method for the ends of a spline beyond the knots.
34 enum ExtrapMethod
35 {
36 ExtrapHeld,
37 ExtrapLinear,
38 ExtrapSloped,
39 ExtrapLoop
40 };
41
42 // Looping modes.
43 enum LoopMode
44 {
45 LoopNone,
46 LoopContinue, // Used by inner loops. Copy whole knots.
47 LoopRepeat, // Used by extrap loops. Repeat with offset.
48 LoopReset, // Used by extrap loops. Repeat identically.
49 LoopOscillate // Used by extrap loops. Alternate forward / reverse.
50 };
51
52 // Features that may be required by splines.
53 enum Feature
54 {
55 FeatureHeldSegments = 1 << 0,
56 FeatureLinearSegments = 1 << 1,
57 FeatureBezierSegments = 1 << 2,
58 FeatureHermiteSegments = 1 << 3,
59 FeatureAutoTangents = 1 << 4,
60 FeatureDualValuedKnots = 1 << 5,
61 FeatureInnerLoops = 1 << 6,
62 FeatureExtrapolatingLoops = 1 << 7,
63 FeatureExtrapolatingSlopes = 1 << 8
64 };
65 using Features = unsigned int;
66
67 // One knot in a spline.
68 struct TS_API Knot
69 {
70 double time = 0;
71 InterpMethod nextSegInterpMethod = InterpHeld;
72 double value = 0;
73 bool isDualValued = false;
74 double preValue = 0;
75 double preSlope = 0;
76 double postSlope = 0;
77 double preLen = 0;
78 double postLen = 0;
79 bool preAuto = false;
80 bool postAuto = false;
81
82 public:
83 Knot();
84 Knot(
85 const Knot &other);
86 Knot& operator=(
87 const Knot &other);
88 bool operator==(
89 const Knot &other) const;
90 bool operator!=(
91 const Knot &other) const;
92 bool operator<(
93 const Knot &other) const;
94 };
95 using KnotSet = std::set<Knot>;
96
97 // Inner-loop parameters.
98 //
99 // The pre-looping interval is times [preLoopStart, protoStart).
100 // The prototype interval is times [protoStart, protoEnd).
101 // The post-looping interval is times [protoEnd, postLoopEnd],
102 // or, if closedEnd is false, the same interval, but open at the end.
103 // To decline pre-looping or post-looping, make that interval empty.
104 //
105 // The value offset specifies the difference between the value at the starts
106 // of consecutive iterations.
107 //
108 // It is common, but not required, to use a subset of functionality:
109 // - Knots at the start and end of the prototype interval
110 // - Whole numbers of loop iterations
111 // (sizes of looping intervals are multiples of size of proto interval)
112 // - Value offset initially set to original value difference
113 // between ends of prototype interval
114 // - closedEnd true
115 //
116 // A knot exactly at the end of the prototype interval is not part of the
117 // prototype. If there is post-looping, a knot at the end of the prototype
118 // interval is overwritten by a copy of the knot from the start of the
119 // prototype interval.
120 //
121 // Enabling inner looping can change the shape of the prototype interval
122 // (and thus all looped copies), because the first knot is echoed as the
123 // last. Inner looping does not aim to make copies of an existing shape; it
124 // aims to set up for continuity at loop joins.
125 //
126 // If closedEnd is true, and there is a whole number of post-iterations, and
127 // there is a knot at the prototype start time, then a final copy of the
128 // first prototype knot will be echoed at the end of the last
129 // post-iteration.
130 //
131 struct TS_API InnerLoopParams
132 {
133 bool enabled = false;
134 double protoStart = 0;
135 double protoEnd = 0;
136 double preLoopStart = 0;
137 double postLoopEnd = 0;
138 bool closedEnd = true;
139 double valueOffset = 0;
140
141 public:
142 InnerLoopParams();
143 InnerLoopParams(
144 const InnerLoopParams &other);
145 InnerLoopParams& operator=(
146 const InnerLoopParams &other);
147 bool operator==(
148 const InnerLoopParams &other) const;
149 bool operator!=(
150 const InnerLoopParams &other) const;
151
152 bool IsValid() const;
153 };
154
155 // Extrapolation parameters for the ends of a spline beyond the knots.
156 struct TS_API Extrapolation
157 {
158 ExtrapMethod method = ExtrapHeld;
159 double slope = 0;
160 LoopMode loopMode = LoopNone;
161
162 public:
163 Extrapolation();
164 Extrapolation(ExtrapMethod method);
165 Extrapolation(
166 const Extrapolation &other);
167 Extrapolation& operator=(
168 const Extrapolation &other);
169 bool operator==(
170 const Extrapolation &other) const;
171 bool operator!=(
172 const Extrapolation &other) const;
173 };
174
175public:
176 TS_API
177 TsTest_SplineData();
178
179 TS_API
180 TsTest_SplineData(
181 const TsTest_SplineData &other);
182
183 TS_API
184 TsTest_SplineData&
185 operator=(
186 const TsTest_SplineData &other);
187
188 TS_API
189 bool operator==(
190 const TsTest_SplineData &other) const;
191
192 TS_API
193 bool operator!=(
194 const TsTest_SplineData &other) const;
195
196 TS_API
197 void SetIsHermite(bool hermite);
198
199 TS_API
200 void AddKnot(
201 const Knot &knot);
202
203 TS_API
204 void SetKnots(
205 const KnotSet &knots);
206
207 TS_API
208 void SetPreExtrapolation(
209 const Extrapolation &preExtrap);
210
211 TS_API
212 void SetPostExtrapolation(
213 const Extrapolation &postExtrap);
214
215 TS_API
216 void SetInnerLoopParams(
217 const InnerLoopParams &params);
218
219 TS_API
220 bool GetIsHermite() const;
221
222 TS_API
223 const KnotSet&
224 GetKnots() const;
225
226 TS_API
227 const Extrapolation&
228 GetPreExtrapolation() const;
229
230 TS_API
231 const Extrapolation&
232 GetPostExtrapolation() const;
233
234 TS_API
235 const InnerLoopParams&
236 GetInnerLoopParams() const;
237
238 TS_API
239 Features GetRequiredFeatures() const;
240
241 TS_API
242 std::string GetDebugDescription() const;
243
244private:
245 bool _isHermite = false;
246 KnotSet _knots;
247 Extrapolation _preExtrap;
248 Extrapolation _postExtrap;
249 InnerLoopParams _innerLoopParams;
250};
251
252PXR_NAMESPACE_CLOSE_SCOPE
253
254#endif