HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CL_SimpleChannel.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: Channel Library (C++)
7  *
8  * COMMENTS: Simplified version of a channel which can be used without
9  * requiring the full CH library
10  *
11 */
12 
13 #ifndef __CL_SimpleChannel_h__
14 #define __CL_SimpleChannel_h__
15 
16 #include "CL_API.h"
17 #include "CL_Types.h"
18 
19 #include <SYS/SYS_Types.h>
20 #include <UT/UT_Array.h>
21 #include <UT/UT_Interval.h>
22 #include <UT/UT_StringHolder.h>
23 #include <UT/UT_SharedPtr.h>
24 #include <UT/UT_Vector2.h>
25 
26 class CL_SegmentValues;
27 class CL_SimpleSegment;
28 class CL_Cubic;
29 
30 class CL_SimpleChannel;
33 
34 class UT_RLEBitArray;
35 
37 {
38 public:
39  fpreal x[4];
40  fpreal y[4];
41 
42  CL_Bezier() {}
43 
44  CL_Bezier(const CL_SegmentValues &sv);
45  CL_Bezier(CL_SegmentValues sv, fpreal vscale, fpreal voff);
46  // This constructor can be used to convert segment values to a bezier
47  // without applying the clamp to the control points which is meant to fix
48  // curves that back in on themselves. We want to prevent this clamping when
49  // converting the end_segment. As it has has a length of 0, clamping will
50  // cause us to lose its control points/acceleration handles.
51  CL_Bezier(const CL_SegmentValues &sv, bool clamp_slopes);
52 
53  void init(const CL_SegmentValues &sv);
54 
55  void fromSegmentValues(const CL_SegmentValues &sv,
56  bool clamp_slopes = true);
57 
58  void getValues( CL_SegmentValues &v ) const;
59 
60  static void getCubicFromCVs( const fpreal x[4], CL_Cubic &c );
61  static void getCubicFromCVs( const fpreal x[4], fpreal c[4] );
62 
63  static void splitInternal( fpreal t, const fpreal xin[4],
64  fpreal xout1[4], fpreal xout2[4] );
65 
66  void splitP( fpreal u, CL_Bezier &a, CL_Bezier &b ) const;
67 
68  void split( fpreal t, CL_Bezier &a, CL_Bezier &b ) const;
69 
70  void splitAndFindSlopeLengths( fpreal t,
71  fpreal &left_in, fpreal &left_out,
72  fpreal &right_in, fpreal &right_out ) const;
73 
74  // Calculates an acceleration ratio for a key to try and ease
75  // the curve if it's at the corner of a steep gradient
76  static fpreal getAdjustedAccelRatio(fpreal v0, fpreal v1, fpreal v2,
77  fpreal t0, fpreal t1, fpreal t2,
78  fpreal slope, bool is_in);
79 
80  fpreal timeToParametric( fpreal t ) const;
81 
82  fpreal evalP( fpreal u ) const;
83 
84  fpreal eval( fpreal t ) const; // t is local
85 
86  void display() const;
87 };
88 
90 {
91 public:
92  fpreal t0, t1;
93  fpreal x0, x1, x2, x3;
94 
95  CL_Cubic() {};
96  CL_Cubic(const CL_SegmentValues &sv);
97  CL_Cubic(fpreal iv, fpreal ov, fpreal im, fpreal om, fpreal it, fpreal ot);
98 
99  void init(const CL_SegmentValues &sv);
100  void getValues(CL_SegmentValues &v) const;
101 
102  fpreal timeToParametric( fpreal t ) const; // t -> u
103 
104  static fpreal reverseEvalP( const fpreal x[4], fpreal y ); // y -> u
105  static fpreal reverseEvalP( const CL_SimpleSegment &seg, fpreal y ); // y -> u
106  fpreal reverseEvalP( fpreal y ) const; // y -> u
107 
108  fpreal evalP( fpreal u ) const // u -> y
109  {
110  return x0 + u*(x1 + u*(x2 + u*x3));
111  }
112 
113  fpreal eval( fpreal t ) const; // t -> y
114 
115  fpreal calculateSlopeP( fpreal u ) const;
116 
117  fpreal calculateAccelP( fpreal u ) const;
118 
119  // If lock_in = true, this computes the range of out slopes that produce
120  // a monotonic curve assuming the in slope is fixed. false does the same
121  // for the in slope assuming the out slope is fixed.
122  // If no such interval exists, sets range to (-CL_MAX_SLOPE, CL_MAX_SLOPE)
123  // and returns false. Returns true if there's a valid interval
124  bool getMonotoneInterval(UT_IntervalR &range, bool lock_in);
125  // Same as getMonotoneInterval, but if the interval doesn't exist then
126  // it is recalculated with the locked slope being clamped to a range where
127  // the interval must be non-empty.
128  // This is useful to find slopes that get as close as possible to
129  // monotonicity, which helps prevent snapping in some cases.
130  void getWeakMonotoneInterval(UT_IntervalR &range, bool lock_in);
131 
132 
133  static bool isMonotone(fpreal iv, fpreal ov, fpreal im, fpreal om, fpreal dt);
134  static void clampSlopesToMonotone(fpreal &in, fpreal &out,
135  fpreal in_val, fpreal out_val, fpreal dt);
136  /// Second derivative discontinuity minimizing method suggested by
137  /// Wolberg. Given the slopes at the surrounding knots, picks a
138  /// slope that gets as close to C2 continuity as possible while
139  /// preserving monotonicity. To be used on keys whose neighbours have
140  /// pre-determined slopes, like local extrema or non-auto slopes
141  static fpreal getMonotoneSlopeSDDE(fpreal v0, fpreal v1, fpreal v2,
142  fpreal t0, fpreal t1, fpreal t2,
143  fpreal m0, fpreal m2);
144  // An extension of getMonotoneSlopeSDDE that operates on a group of
145  // 2 keys sandwiched between knots with fixed slopes. Picks slopes for
146  // to approach C2 continuity at both knots simultaneously while
147  // preserving monotonicity
148  static void getMonotoneSlopeSDDE2(fpreal v0, fpreal v1, fpreal v2, fpreal v3,
149  fpreal t0, fpreal t1, fpreal t2, fpreal t3,
150  fpreal m0, fpreal &m1, fpreal &m2, fpreal m3);
151 
152  // An unstable extension of getMonotoneSlopeSDDE2 that uses conic intersections
153  // to resolve cases where the segments are non monotonic.
154  #if 0
155  static void getMonotoneSlopeSDDE2ViaConic
157  fpreal t0, fpreal t1, fpreal t2, fpreal t3,
158  fpreal m0, fpreal &m1, fpreal &m2, fpreal m3);
159  #endif
160 
161 
162  void display() const;
163 };
164 
165 // Supported SimpleSegment Types.
167 {
177  // Custom means an expression that is unsupported by
178  // the simple channel. The custom expression will be stored
179  // on the simpleSegment for purposes of preserving it when
180  // round-tripping back to a CH_Segment, but it will be
181  // evaluated as a Bezier instead of the actual type.
183 };
184 
185 class CL_SimpleChannel;
186 
187 enum class CL_KeyHalf
188 {
189  In,
190  Out,
191  InOut,
192 };
193 
195 {
196 public:
197  fpreal t0, t1;
198  fpreal iv, ov, im, om, isl, osl;
199 
201 
202  void display();
203 };
204 
205 // It is designed for fast evaluation of the supported segment types.
206 // with focus on the bezier segments.
208 {
209 public:
210  fpreal getStart() const { return myBezierX[0]; }
211  fpreal getEnd() const { return myBezierX[3]; }
212  fpreal getStartValue() const { return myBezierY[0]; }
213  fpreal getEndValue() const { return myBezierY[3]; }
214  fpreal getLength() const { return myBezierX[3] - myBezierX[0]; }
215 
216  void setType(CL_SimpleSegmentType type) { myType = type; }
217  CL_SimpleSegmentType getType() const { return myType; }
218 
219  void setExtraData(int index, fpreal data) { myExtra[index] = data; }
220  fpreal *getExtraData() { return myExtra; }
221 
222 private:
223 
224  //x[0] is the start time
225  //x[3] is the end time
226  //y[0] is the start value
227  //y[3] is the end value
228  fpreal myBezierX[4]; // x[] data member of CL_Bezier
229  fpreal myBezierY[4]; // y[] data member of CL_Bezier
230 
231  CL_SimpleSegmentType myType; // Simple Segment Type
232 
233  // Extra data for Bezier/Cubic/Quintic
234  // Bezier stores UT_BezierRootFinder precomputed coefficients
235  // Cubic stores InSlope and OutSlope
236  // Quintic stores InSlope, OutSlope, InAccel and OutAcce
237  fpreal myExtra[16];
238 
239  friend class CL_SimpleChannel;
240  friend class CL_Cubic;
241 };
242 
243 /// A specialized channel for fast evaluation.
244 /// Should be created from an existing CH_Channel using
245 /// CH_Channel->asSimpleChannel().
246 /// Can be copied using the copy constructor.
247 /// Doesn't store the in/out value/slope/accel directly.
248 /// It stores precomputed bezier coefficient to avoid doing the conversion at
249 /// each evaluation.
250 /// Also uses UT_BezierRootFinder with precomputed coefficients to speed up
251 /// CL_Cubic::reverseEvalP.
253 {
254 public:
255  // Create an empty channel
257 
259  fpreal start,
260  int num_segments,
261  fpreal length,
262  CL_ChannelBehavior left_type,
263  CL_ChannelBehavior right_type,
264  fpreal default_value,
265  fpreal default_slope);
266 
267  // Deprecated, use the variant without tolerance instead
268  SYS_DEPRECATED(20.0)
270  fpreal start,
271  int num_segments,
272  fpreal length,
273  CL_ChannelBehavior left_type,
274  CL_ChannelBehavior right_type,
275  fpreal default_value,
276  fpreal default_slope,
277  fpreal tolerance);
278 
279  ~CL_SimpleChannel() = default;
280 
281  CL_SimpleChannel(const CL_SimpleChannel &other) = default;
282  CL_SimpleChannel(CL_SimpleChannel &&other) = default;
283 
284  CL_SimpleChannel &operator=(const CL_SimpleChannel &other) = default;
285  CL_SimpleChannel &operator=(CL_SimpleChannel &&other) = default;
286 
287  /// Simple channels can only evaluate certain types of segments.
288  /// This scans the channel to see if there is anything that can't
289  /// be eval'ed and returns true if everything is safe for eval()
290  bool canEval() const;
291 
292  /// Evaluate the channel at global time.
293  /// @param gtime The global time at which to evaluate the channel.
294  /// @param no_disabling If true, the evaluation ignores any disabled
295  /// segments.
296  fpreal eval(fpreal gtime, bool no_disabling = false) const;
297 
298  /// Evaluate the channel at global time using a segment hint.
299  /// @param gtime The global time at which to evaluate the channel.
300  /// @param segment_idx_hint The segment hint. Start with an hint of -1 if
301  /// you don't have a previous evaluation.
302  /// @param no_disabling If true, the evaluation ignores any disabled
303  /// segments.
304  fpreal eval(fpreal gtime, int &segment_idx_hint,
305  bool no_disabling = false) const;
306 
307  // Evaluate the segment at local time using a segment hint.
308  fpreal eval(const CL_SimpleSegment &seg, fpreal ltime) const;
309 
310  fpreal evalSlope(fpreal gtime) const;
311  // Evaluate the slope at local time using a segment hint.
312  fpreal evalSlope(const CL_SimpleSegment &seg, fpreal ltime) const;
313 
314  fpreal evalAccel(fpreal gtime) const;
315  // Evaluate the slope at local time using a segment hint.
316  fpreal evalAccel(const CL_SimpleSegment &seg, fpreal ltime) const;
317 
318  bool isAtHardKey(fpreal gtime) const;
319 
320  int getSegmentIdx(fpreal ltime) const;
321  CL_SimpleSegment &getSegment(int index) { return mySegments[index]; }
322  const CL_SimpleSegment &getSegment(int index) const { return mySegments[index]; }
323  const UT_Array<CL_SimpleSegment> &getSegments() const { return mySegments; }
324 
325  UT_StringHolder getSegmentExpression(int index) const { return mySegmentExpressions[index]; }
326  const UT_Array<UT_StringHolder> &getSegmentExpressions() const { return mySegmentExpressions; }
328  { mySegmentExpressions[index] = expr; }
329 
331  { return mySegmentInSlopesAuto[index]; }
333  { return mySegmentOutSlopesAuto[index]; }
334 
336  { mySegmentInSlopesAuto[index] = value; }
338  { mySegmentOutSlopesAuto[index] = value; }
339 
340  void setSegmentInSlope(int index, fpreal slope);
341  void setSegmentOutSlope(int index, fpreal slope);
342  void setSegmentInAccel(int index, fpreal accel, bool ratio = false);
343  void setSegmentOutAccel(int index, fpreal accel, bool ratio = false);
344 
345  /// Set the type of the segment
346  /// Note that this differs from the setSegmentExpression, which is used
347  /// only for custom expressions.
348  /// @param index The index of the segment to modify
349  /// @param type The type to change the segment to.
350  void setSegmentType(int index, CL_SimpleSegmentType type);
351 
352  CL_SimpleSegmentType getSegmentType(int index) const;
353 
354  /// Insert a key frame at the given global time.
355  /// Returns true if a key frame was added, or false if it failed, or if
356  /// there was already a key frame at the given time.
357  bool insertKeyFrame(fpreal global_time, bool auto_slope = true);
358 
359  /// Destroy the key frame at the given global time
360  /// Returns true if a key was deleted, or false if there was no key at this
361  /// time
362  bool destroyKeyFrame(fpreal global_time);
363 
364  /// Destroys all key frames in the given global time range, inclusive.
365  /// Returns true if a key was deleted, or false if there were no keys in this
366  /// range
367  bool destroyKeyFrames(fpreal gtime_start, fpreal gtime_end);
368 
369  /// Destroys all segments from start_idx to end_idx.
370  /// Returns true if a key was deleted, or false if there were no keys in this
371  /// range
372  /// This keeps all the values/times in sync.
373  /// start_idx and end_idx are inclusive
374  /// end_idx of -1 means the last segment.
375  bool destroySegments(int start_idx, int end_idx);
376 
377  /// Set the value of the key at the given time
378  /// @param gtime Global time of the key to change
379  /// @param value New value to set for the key
380  /// @param half Which half of the key to set. Defaults to both (tied)
381  /// @returns true if successful, or false if there is no key at the given time
382  bool setKeyValue(fpreal gtime, fpreal value,
384 
385  /// Set the slope of the key at the given time
386  /// @param gtime Global time of the key to change
387  /// @param slope New slope to set for the key
388  /// @param half Which half of the key to set. Defaults to both (tied)
389  /// @returns true if successful, or false if there is no key at the given time
390  bool setKeySlope(fpreal gtime, fpreal slope,
392 
393  /// Set the accel of the key at the given time
394  /// @param gtime Global time of the key to change
395  /// @param accel New value to set for the key
396  /// @param half Which half of the key to set. Defaults to both (tied)
397  /// @returns true if successful, or false if there is no key at the given time
398  bool setKeyAccel(fpreal gtime, fpreal accel,
400 
401  fpreal getKeyValue(fpreal gtime, CL_KeyHalf half = CL_KeyHalf::InOut) const;
402  fpreal getKeySlope(fpreal gtime, CL_KeyHalf half = CL_KeyHalf::InOut) const;
403  fpreal getKeyAccel(fpreal gtime, CL_KeyHalf half = CL_KeyHalf::InOut) const;
404 
405  /// Set the auto_slope property of the key at the given time
406  /// @param gtime Global time of the key to change
407  /// @param auto_slope New auto_slope to set for the key
408  /// @param half Which half of the key to set. Defaults to both (tied)
409  /// @returns true if successful, or false if there is no key at the given
410  /// time
411  bool setKeyAutoSlope(fpreal gtime, bool auto_slope,
413 
414  /// Sets data evenly spaced between from and to
415  bool setRawValues(fpreal from,
416  fpreal to,
417  fpreal *data,
418  int num_samples,
419  bool auto_slope = true);
420  /// Sets data at the specified times
421  bool setRawValues(fpreal *times, fpreal *data, int num_samples);
422 
423  /// clears the channel, erasing all segments
424  void clear();
425 
426  /// Set the default value. This is the value returned when evaluating
427  /// an empty channel.
428  void setDefaultValue(fpreal value) { myDefaultValue = value; }
429 
430  void setPreValue(fpreal value) { myPreValue = value; }
431  void setPreSlope(fpreal slope) { myPreSlope = slope; }
432  void setPreType(CL_ChannelBehavior type) { myPreType = type; }
433 
434  void setPostValue(fpreal value) { myPostValue = value; }
435  void setPostSlope(fpreal slope) { myPostSlope = slope; }
436  void setPostType(CL_ChannelBehavior type) { myPostType = type; }
437 
438  fpreal getDefaultValue() const { return myDefaultValue; }
439 
440  fpreal getPreValue() const { return myPreValue; }
441  fpreal getPreSlope() const { return myPreSlope; }
442  CL_ChannelBehavior getPreType() const { return myPreType; }
443 
444  fpreal getPostValue() const { return myPostValue; }
445  fpreal getPostSlope() const { return myPostSlope; }
446  CL_ChannelBehavior getPostType() const { return myPostType; }
447 
448  bool isAllDisabled() const;
449  bool isAllEnabled() const;
450  bool isDisabled(fpreal gtime) const;
451  void disableAll(fpreal gtime);
452  void enableAll();
453  void disable(fpreal gstart, fpreal gend);
454  void enable(fpreal gstart, fpreal gend);
455 
457  { return myDisableSegments; }
458  fpreal getDisabledValue() const { return myDisabledValue; }
459  void setDisabledValue(fpreal value) { myDisabledValue = value; }
460 
461  // Set the disable segments directly. Segments must be sorted by start time
462  // and non-overlapping. This is intended for round-tripping from CH_Channel.
463  void setDisableSegments(const UT_Array<UT_Vector2R> &segs);
464 
467 
468  SYS_DEPRECATED(20.0)
469  void setTolerance(fpreal tolerance) { myTolerance = tolerance; }
470 
471 
472  // map collection time to channel time...
473  inline fpreal localTime(fpreal t) const { return (t-myStart); }
474 
475  // map channel time to global time...
476  inline fpreal globalTime(fpreal t) const { return t + myStart; }
477 
478  fpreal getStart() const { return myStart; }
479  fpreal getEnd() const { return myStart + myLength; }
480  fpreal getLength() const { return myLength; }
481  void setStart(fpreal start) { myStart = start; }
482 
483  /// Returns the number of segments including the end segment
484  int getNSegments() const { return mySegments.size(); }
485 
486  UT_Array<fpreal> getKeyTimes() const;
487  UT_Array<fpreal> getKeyValues(CL_KeyHalf half = CL_KeyHalf::InOut) const;
488  UT_Array<fpreal> getKeySlopes(CL_KeyHalf half = CL_KeyHalf::InOut) const;
489  UT_Array<fpreal> getKeyAccels(CL_KeyHalf half = CL_KeyHalf::InOut) const;
490 
491  /// Returns the start and end global times of the first and last keys.
492  /// This is different than myStart and myStart+myLength because myStart
493  /// is set to 0.0 almost all the time.
494  /// Returns true and a valid range if there is at least one key.
495  /// Returns false if there is no key and start and end get the myStart value.
496  bool getKeyTimeRange(fpreal &start, fpreal &end) const;
497 
498  void setKeys(const UT_Array<fpreal> *values = nullptr,
499  const UT_Array<fpreal> *slopes = nullptr,
500  const UT_Array<fpreal> *accels = nullptr,
502  void setKeyValues(const UT_Array<fpreal> &values,
504  void setKeySlopes(const UT_Array<fpreal> &slopes,
506  void setKeyAccels(const UT_Array<fpreal> &accels,
508 
509  bool getSurroundingSegs(fpreal gtime, CL_SimpleSegment *&left,
511 
512  bool getSurroundingSegs(fpreal gtime, const CL_SimpleSegment *&left,
513  const CL_SimpleSegment *&right) const;
514 
515  /// Shift the specified keys by the given time offsets.
516  /// Time offsets must either match the size of indices, or be an array
517  /// of 1 element to shift all keys by the same offset.
518  bool moveKeysWithDeltas(const UT_IntArray &indices,
519  const UT_Array<fpreal> &time_offsets);
520 
521  /// Move a list of keys using a list of time offset and value offsets.
522  /// Do the same as CHmoveKeysWithDeltas for CH_Channel
523  void moveKeysWithDeltas(
524  const UT_Array<fpreal> &key_times,
525  const UT_Array<fpreal> &time_offsets,
526  const UT_Array<fpreal> &value_offsets);
527 
528  void smoothAutoSlopesForSegments(
529  UT_RLEBitArray &slope_flags,
530  bool force = false,
531  fpreal max_delta = -1);
532 
533  void smoothAutoSlopes(bool force = false);
534 
535  /// inserts a key at gtime and destroys all keys before it.
536  /// does nothing if gtime is before the channel start.
537  void trimStart(float gtime);
538  /// inserts a key at gtime and destroys all keys after it.
539  /// does nothing if gtime is after the channel end.
540  void trimEnd(float gtime);
541 
542  // The following four functions are called by the CH_Manager to ensure
543  // simple channels share the same default animation preferences that
544  // regular channels do.
545  static void setChannelTolerance(fpreal tol) { theTolerance = tol; }
546  /// Set the segment type used for the first key in a channel
547  static void setDefaultSegmentType(CL_SimpleSegmentType type);
548  /// Set the segment type used when splitting a segment if auto split is
549  /// false
550  static void setDefaultSegmentSplitType(CL_SimpleSegmentType type);
551  /// Set the segment type behaviour when splitting a segment. If true,
552  /// The type of the split segment will be applied to the new segment,
553  /// otherwise, theDefaultSplitSegmentType will be used
554  static void setAutoSplit(bool onoff);
555 
556  static fpreal getChannelTolerance() { return theTolerance; }
557 
559  { return theDefaultSegmentType; }
560 
562  { return theDefaultSplitSegmentType; }
563 
564  static bool getAutoSplit() { return theAutoSplit; }
565 
566 private:
567  static fpreal theTolerance;
568  static constexpr fpreal theDefaultAccelRatio = 1.0 / 3.0;
569  static CL_SimpleSegmentType theDefaultSegmentType;
570  static CL_SimpleSegmentType theDefaultSplitSegmentType;
571  static bool theAutoSplit;
572 
573  // should be kept in sync with CH_Segment::getAccelFromRatio
574  static fpreal getAccelFromRatio(fpreal slope, fpreal ratio,
575  fpreal length)
576  {
577  if( length==0.0 )
578  length = 1.0;
579  return length * ratio * SYSsqrt( slope*slope + 1 );
580  }
581 
582  // These methods are adapted from CH_Segment::clamp{In,Out}Accel. They
583  // serve as an alternative to the clamp_slopes option in
584  // CL_Bezier::fromSegmentValues, clamping the acceleration instead of the
585  // slope.
586  /// Clamp a SegmentValues' in acceleration to fix a curve that would
587  /// back in on itself.
588  static fpreal clampSegmentValuesInAccel(const CL_SegmentValues &sv,
589  bool is_end_segment);
590  /// Clamp a SegmentValues' out acceleration to fix a curve that would
591  /// back in on itself.
592  static fpreal clampSegmentValuesOutAccel(const CL_SegmentValues &sv,
593  bool is_end_segment);
594 
595  bool extend(fpreal t, int &i, fpreal &ret) const;
596 
597  void splitSegment(fpreal gtime, bool auto_slope = true);
598  /// Change a segment's length, preserving its start time and in/out slopes
599  void changeSegmentLength(int index,
600  fpreal new_length,
601  bool scale_accels = true);
602 
603  // Methods for manipulating the segments array.
604  // Note that the following 4 functions do not change the segment data,
605  // But rather just ensure that the various arrays (segment, expression,
606  // in/out slope) are kept in sync when segments are moved.
607  // It is up to the caller to ensure that the segment values/times are
608  // correct when calling these methods.
609  void appendSegment(const CL_SimpleSegment &segment,
610  const UT_StringHolder &expr,
611  bool auto_slope);
612  void insertSegment(int index,
613  const CL_SimpleSegment &segment,
614  const UT_StringHolder &expr,
615  bool auto_slope);
616  void removeSegment(int index);
617 
618  CL_SegmentValues getValuesFromSegment(CL_SimpleSegment &segment);
619  void setSegmentFromValues(CL_SimpleSegment &segment,
620  const CL_SegmentValues &sv,
621  bool clamp_slopes = true);
622 
623  /// Call removeRange on the segment arrays
624  /// end_index is inclusive unlike UT_Array::removeRange.
625  void removeSegments(int start_index, int end_index);
626 
627  /// Recompute the bezier coeffs for each segment, in the given range
628  void recomputeBezierCoeffs(int start_index = 0, int end_index = -1);
629  void recomputeBezierCoeffs(CL_SimpleSegment &segment);
630 
631  /// Sets the extra data for the segment, based on its type.
632  void setSegmentExtraData(CL_SimpleSegment &segment);
633 
634  /// Moves a key/segment by the given time delta.
635  /// Requires that the new time does NOT have a key at it already
636  void shiftKey(int index, fpreal t, bool recompute_coeffs = true);
637 
638  /// Returns whether or not a segment is an end segment (ie, has length == 0)
639  bool isEndSegment(const CL_SimpleSegment &segment) const;
640 
641  int getDisableSegmentIndex(fpreal ltime, bool closest_earlier = false) const;
642 
643  // Compact array of segments.
644  // This data layout currently works well when evaluating a single channel
645  // many times across its whole time range.
646  // We might have to change the data layout to be more efficient
647  // at evaluating many channels at the same global time.
648  // This could involve a page system where segments from the same time range
649  // are from the same area in a memory pool.
650  UT_Array<CL_SimpleSegment> mySegments;
651 
652  // Custom expressions for each segment with a type of CUSTOM.
653  // Stored for purposes of round-tripping back to CH_Channel only - these
654  // segments will still be evaluated as Beziers here.
655  UT_Array<UT_StringHolder> mySegmentExpressions;
656 
657  // Whether the in/out slope for each segment is auto calculated or not
658  // Stored for purposes of round-tripping back to a CH_Channel. These
659  // are currently not used when setting the key value of a simple channel.
660  // TODO(michaelf): Do we want to support auto-slope calculation when setting
661  // keys of simplechannels?
662  UT_Array<bool> mySegmentInSlopesAuto;
663  UT_Array<bool> mySegmentOutSlopesAuto;
664 
665  fpreal myTolerance; // Global floating point tolerance.
666  fpreal myLength; // Channel Length in time.
667  fpreal myStart; // Channel Start global time.
668 
669  // Constant value to be used if the channel is empty.
670  fpreal myDefaultValue;
671  // Precomputed values for pre/post extend.
672  fpreal myPreValue;
673  fpreal myPostValue;
674 
675  // Precomputed slope (or extra) for pre/post extend.
676  fpreal myPreSlope;
677  fpreal myPostSlope;
678 
679  // Pre/right types, used by extend()
680  CL_ChannelBehavior myPreType;
681  CL_ChannelBehavior myPostType;
682 
683  UT_Array<UT_Vector2R> myDisableSegments;
684 
685  // Since CL doesn't have access to the CH_Manager to get the global start
686  // and end time, we need to track whether or not the full channel is
687  // disabled manually
688  bool myIsAllDisabled;
689  fpreal myDisabledValue;
690 };
691 
692 #endif
type
Definition: core.h:556
const UT_Array< CL_SimpleSegment > & getSegments() const
fpreal getPostSlope() const
GLsizei GLenum const void * indices
Definition: glcorearb.h:406
GLenum GLint * range
Definition: glcorearb.h:1925
#define SYS_DEPRECATED(__V__)
GA_API const UT_StringHolder accel
imath_half_bits_t half
if we're in a C-only context, alias the half bits type to half
Definition: half.h:268
void
Definition: png.h:1083
GLint left
Definition: glcorearb.h:2005
GLboolean * data
Definition: glcorearb.h:131
const UT_Array< UT_StringHolder > & getSegmentExpressions() const
const GLdouble * v
Definition: glcorearb.h:837
CL_ChannelBehavior getPreType() const
GLuint start
Definition: glcorearb.h:475
int getNSegments() const
Returns the number of segments including the end segment.
GLsizei const GLfloat * value
Definition: glcorearb.h:824
void setPostType(CL_ChannelBehavior type)
GLdouble right
Definition: glad.h:2817
static CL_SimpleSegmentType getDefaultSegmentType()
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
UT_StringHolder getSegmentExpression(int index) const
void setPreType(CL_ChannelBehavior type)
GLint y
Definition: glcorearb.h:103
fpreal getLength() const
fpreal getDisabledValue() const
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:818
GLfloat GLfloat GLfloat GLfloat v3
Definition: glcorearb.h:819
void setStart(fpreal start)
fpreal getEndValue() const
const UT_Array< UT_Vector2R > & getDisableSegments() const
constexpr auto in(type t, int set) -> bool
Definition: core.h:611
GLdouble GLdouble x2
Definition: glad.h:2349
UT_SharedPtr< const CL_SimpleChannel > CL_SimpleChannelConstPtr
CL_SimpleSegmentType
const CL_SimpleSegment & getSegment(int index) const
void setType(CL_SimpleSegmentType type)
#define CL_API
Definition: CL_API.h:10
fpreal getEnd() const
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
void setDefaultValue(fpreal value)
fpreal * getExtraData()
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
int getSegmentInSlopeAuto(int index) const
void setSegmentInSlopeAuto(int index, bool value)
fpreal getStart() const
GLuint GLuint end
Definition: glcorearb.h:475
void setSegmentOutSlopeAuto(int index, bool value)
void setSegmentExpression(int index, const UT_StringHolder &expr)
fpreal localTime(fpreal t) const
fpreal getTolerance() const
CL_KeyHalf
void setExtraData(int index, fpreal data)
void setPreSlope(fpreal slope)
HUSD_API bool eval(VtValue &val, T &ret_val)
fpreal getEnd() const
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
CL_SimpleSegmentType getType() const
fpreal getDefaultValue() const
GLdouble t
Definition: glad.h:2397
GLfloat v0
Definition: glcorearb.h:816
CL_ChannelBehavior
Definition: CL_Types.h:18
void setPreValue(fpreal value)
UT_SharedPtr< CL_SimpleChannel > CL_SimpleChannelPtr
static CL_SimpleSegmentType getDefaultSegmentSplitType()
fpreal getLength() const
fpreal evalP(fpreal u) const
SIM_API const UT_StringHolder force
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
static void setChannelTolerance(fpreal tol)
fpreal64 fpreal
Definition: SYS_Types.h:283
CL_ChannelBehavior getPostType() const
fpreal getPreValue() const
static fpreal getChannelTolerance()
LeafData & operator=(const LeafData &)=delete
void setPostSlope(fpreal slope)
GLuint index
Definition: glcorearb.h:786
GLfloat GLfloat v1
Definition: glcorearb.h:817
fpreal globalTime(fpreal t) const
int getSegmentOutSlopeAuto(int index) const
fpreal getPreSlope() const
fpreal getStart() const
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
fpreal getPostValue() const
static bool getAutoSplit()
GA_API const UT_StringHolder segs
CL_SimpleSegment & getSegment(int index)
void setDisabledValue(fpreal value)
Definition: format.h:1821
void setPostValue(fpreal value)
fpreal getStartValue() const