HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CH_Channel.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: Definition of a channel
9  *
10  */
11 
12 #ifndef __CH_Channel_h__
13 #define __CH_Channel_h__
14 
15 #include "CH_API.h"
16 #include "CH_Collection.h"
17 #include "CH_ExprLanguage.h"
18 #include "CH_EventManager.h"
19 #include "CH_Manager.h"
20 #include "CH_Segment.h"
21 #include "CH_Types.h"
22 
23 #include <UT/UT_Array.h>
24 #include <UT/UT_Assert.h>
25 #include <UT/UT_Debug.h>
26 #include <UT/UT_Interval.h>
27 #include <UT/UT_NonCopyable.h>
28 #include <UT/UT_RLEBitArray.h>
29 #include <UT/UT_String.h>
30 #include <UT/UT_StringHolder.h>
31 #include <UT/UT_SuperInterval.h>
32 #include <UT/UT_Swap.h>
33 #include <UT/UT_VectorTypes.h>
34 
35 #include <SYS/SYS_Inline.h>
36 #include <SYS/SYS_Math.h>
37 #include <SYS/SYS_StaticAssert.h>
38 #include <SYS/SYS_Types.h>
39 #include <iosfwd>
40 #include <stddef.h>
41 
42 
43 class UT_IStream;
45 class CL_SimpleChannel;
46 
48 {
49 public:
51  bool myVValid[ CH_NUM_VALUES ];
52  bool myVTied[ CH_NUM_VALUES ];
53  bool myVAuto[ CH_NUM_VALUES ];
54 };
55 
57 {
58 public:
61  CH_HalfKey k[2];
62 
63  CH_Key() { clear(); }
64 
65  void display() const;
66 
67  void clear();
68 
69  // direction is one of -1, 0, 1
70  // -1 = tie using left value
71  // 0 = tie averaging both
72  // 1 = tie using right value
73  void tie( int direction, CH_ValueTypes t );
74 
75  void tie( int direction );
76 
77  void setAuto( CH_ValueTypes t );
78 
79  void set( CH_ValueTypes t, fpreal value );
80  bool isSet( CH_ValueTypes t ) const;
81 
82  void complete();
83 
84  void get( CH_Segment *left_seg, CH_Segment *right_seg,
85  bool accel_ratio = true );
86 
87  void put( CH_Segment *left_seg, CH_Segment *right_seg,
88  bool accel_ratio = true, bool update_fake_slope_accel_handles = true ) const;
89 
90  void stretch( fpreal xscale, fpreal yscale, bool accel_ratio );
91 
92  void changeAccelsToRatios( fpreal left_seg_len, fpreal right_seg_len );
93 
94  void reverse();
95 
96  void opscript( std::ostream &os, bool use_time,
97  bool only_valid=true ) const;
98 
99  bool verify( bool check_tied_slopes=true ) const;
100 };
101 
102 class CH_API CH_FullKey: public CH_Key
103 {
104 public:
108 
110  {
111  myUseExpression = false;
112  myExprLanguage = CH_OLD_EXPR_LANGUAGE;
113  }
114 
115  CH_FullKey( CH_FullKey const& other );
116  CH_FullKey &operator=( CH_FullKey const& other );
117 
118  void display() const;
119 };
120 
122 {
123 public:
127 
129  {
130  myUseRevExpression = false;
131  myRevExprLanguage = CH_OLD_EXPR_LANGUAGE;
132  }
133 
134  CH_ReversibleKey( CH_ReversibleKey const& other );
136 
137  void display() const;
138 
139  void stretch( fpreal xscale, fpreal yscale, bool accel_ratio );
140 
141  void reverse();
142 };
143 
144 //
145 // Iterator for going through .chn and .bchn files,
146 // channel by channel, until the end of channels for current collection is
147 // reached. The iterator can be restarted by calling begin() again.
148 //
150 {
151 // After using begin or nextChannel, the position in the stream
152 // will be proper for using CH_Channel::load or CH_Collection::loadChannelRange
153 public:
155  bool begin(UT_StringHolder &name, const UT_StringHolder *path=nullptr);
156  bool end() { return myNoMoreChannels; }
157  bool nextChannel(UT_StringHolder &name);
158  int getLastError() { return myLastError; }
159 
160 private:
161  UT_IStream *myCurrIs;
162  UT_StringRef myCurrColl;
163  int myIsBinary;
164  int myLastError;
165  bool myNoMoreChannels;
166 };
167 
168 
170 {
171 public:
172  typedef enum
173  {
177  SNAP_REPLACE_DOUBLE
178  } SnapType;
179 
181  fpreal default_value = 0,
182  const char *default_string = nullptr, bool temporary=false);
183  CH_Channel(CH_Collection *dad, const CH_Channel &from);
184  CH_Channel(CH_Collection *dad, const CH_Channel &from, bool temporary);
185  ~CH_Channel();
186 
188 
189  void initializeFirstSegment(const char *expr,
190  CH_ExprLanguage language);
191 
192  // Initialize parents of mySegments and myDisableSegments to this
193  void initializeSegmentParents();
194 
195  // UTILITIES
196 
197  /// Clear everything, even the defaults.
198  void clear();
199  void swap( CH_Channel &other );
200 
201  const UT_StringHolder &getName() const { return myName; }
202  const UT_StringHolder &getAlias() const
203  {
204  if (myAlias.isstring())
205  return myAlias;
206  else
207  return myName;
208  }
209 
211  {
212  getCollection()->getFullPath(this, path);
213  }
215  {
216  getCollection()->getFullPath(this, path);
217  }
218 
219  // Used only by CH_Collection
220  void setName(const UT_StringHolder &s) { myName = s; }
221  void setAlias(const UT_StringHolder &s) { myAlias = s; }
222 
223  CH_Manager *getManager() const { return myParent->getManager(); }
224 
226  { return getManager()->getTolerance(); }
227 
228  // This returns if the channel is time dependent without evaluating
229  // the channel.
230  bool isTimeDependent() const;
231 
232  // These return if the channel is time dependent and will catch more cases
233  // than isTimeDependent() by evaluating the channel.
234  bool isTimeDependentSlow(int thread) const;
235  bool isStringTimeDependentSlow(int thread) const;
236 
237  bool hasNonIntegerKeys() const;
238  bool isDataDependent(fpreal gtime) const;
239 
240  // are we using a zero-length segment to represent one key?
241  bool hasOnlyOneSegment() const;
242 
243  bool isRotationChannel() const;
244 
245  // KEYS
246  bool getSurroundingSegs( fpreal gtime,
247  CH_Segment *&left, CH_Segment *&right ) const;
248 
249  CH_Segment *getSegmentAfterKey( fpreal gtime ) const;
250 
251  // isAtKey returns true if the channel is considered modifiable at
252  // the given time. This means there's either no segment there or the
253  // segment is constant or there's a timemark there (segment start|end).
254  bool isAtKey(fpreal gtime) const;
255 
256  // isAtHardKey returns true only if there's a timemark (segment start
257  // or end) at the given time. seg_out will receive the segment
258  // containing the key (if found).
259  bool isAtHardKey(fpreal gtime,
260  CH_Segment **seg_out) const;
261  bool isAtHardKey(fpreal gtime) const;
262  bool isAtHardKeyframe(int frame) const;
263 
264  fpreal findKey(fpreal gtime, fpreal direction) const;
265  int findKeyframe(int frame, int direction) const;
266 
269 
270  /// Return an iterator for keys within the given interval. If ascending is
271  /// false, then the iterator is initialized at the end of the range
272  /// instead of at the beginning of the range.
273  /// @{
274  IntervalIter intervalIter(
275  const UT_SuperIntervalR & range,
276  const bool ascending=true) const;
277  ConstIntervalIter constIntervalIter(
278  const UT_SuperIntervalR & range,
279  const bool ascending=true) const;
280  /// @}
281 
282  // sample functions evaluate the channel to find values
283  // getKey functions only evaluate if the time is not already at a hard key
284  void sampleValueSlope( CH_Segment *seg, fpreal gtime,
285  int thread, fpreal &v, fpreal &s );
286  bool sampleVSA( CH_Segment *seg, fpreal gtime, int thread,
287  fpreal &v, fpreal &s, fpreal a[2] );
288  void sampleKey( CH_Segment *seg, fpreal gtime, int thread,
289  CH_Key &key );
290  bool getKey( fpreal gtime, CH_Key &key,
291  bool accel_ratios, CH_GetKeyExtend extend,
292  CH_Segment **left_out, CH_Segment **right_out );
293  bool getKey( fpreal gtime, CH_Key &key,
294  bool accel_ratios = true,
296  bool getFullKey( fpreal gtime, CH_FullKey &key,
297  bool reverse, bool accel_ratios,
298  CH_GetKeyExtend extend,
299  CH_Segment **left_out, CH_Segment **right_out );
300  bool getFullKey( fpreal gtime, CH_FullKey &key,
301  bool reverse = false,
302  bool accel_ratios = true,
304  bool getReversibleKey( fpreal gtime, CH_ReversibleKey &key );
305 
306  void putKey( fpreal gtime, CH_Key const& key,
307  bool accel_ratios, bool apply_auto_slope,
308  bool update_fake_slope_accel_handles);
309  // Returns the segment at the new key, or nullptr on failure.
310  CH_Segment *putFullKey( fpreal gtime, CH_FullKey const& key,
311  bool accel_ratios, bool apply_auto_slope,
312  bool update_fake_slope_accel_handles);
313 
314  void putKey( fpreal gtime, CH_Key const& key,
315  bool accel_ratios = true, bool apply_auto_slope = true )
316  {
317  putKey(gtime, key, accel_ratios, apply_auto_slope, true);
318  }
319  CH_Segment *putFullKey( fpreal gtime, CH_FullKey const& key,
320  bool accel_ratios = true, bool apply_auto_slope = true )
321  {
322  return putFullKey(gtime, key, accel_ratios, apply_auto_slope, true);
323  }
324 
325  void transferKey(fpreal to_time,
326  CH_Channel *from_chp, fpreal from_time);
327 
328  void applyPendingToKey( CH_Key &key, fpreal gtime );
329  void applyDefaultSlopeToKey( CH_Key &key );
330 
331  /// Insert key at given time
332  void insertKeyFrame(fpreal global_t, bool use_auto_slope_pref=true);
333 
334  /// Delete key at given time
335  void destroyKeyFrame(fpreal global_t,
336  bool smooth_auto_slopes);
337  void destroyKeyFrame(fpreal global_t);
338 
339  /// Move key from old time to new time. Requires that a key exists at
340  /// old_gtime and that there is no key at new_gtime.
341  void moveKeyFrame( fpreal old_gtime, fpreal new_gtime );
342  void moveKeyFrame( fpreal old_gtime, fpreal new_gtime, CH_BatchModifyScope &scope );
343 
344  void saveKeyFrameForUndo( fpreal global_t );
345  void saveForUndo();
346 
347  // this function is a bit confusing
348  // Sets the in/out values for a segment to the val at a time specified
349  //The method returns 0 if it was successfull,
350  // -1 if there was no key at the time specified
351  // set_pending = if true,the pending value is set to val, unless commit_keys
352  // is true, and gtime falls on a key frame.
353  // commit_keys = if true and gtime falls on a key frame, the keyed value
354  // for that frame is set to val, pending is cleared if
355  // set_pending is true
356  int setKeyValue(fpreal val, fpreal gtime,
357  bool set_pending = false,
358  bool commit_keys = true,
359  bool propagate = true);
360  int setKeyString(const UT_String &str, fpreal gtime,
361  bool set_pending = false,
362  bool commit_keys = true,
363  bool propagate = true);
364  int setKeyString(const UT_String &str, fpreal gtime,
365  CH_ExprLanguage language,
366  bool set_pending = false,
367  bool commit_keys = true,
368  bool propagate = true);
369  void holdValue( fpreal gtime, int thread );
370 
371  // utility functions for getting keyframe numbers:
372  // they return array of keyframes in the channel
373  // the frames are unique and sorted in a ascending order.
374  void getKeyFrames(const UT_SuperIntervalR &range,
375  UT_Array<int> &frames,
376  bool error_frames_only);
377 
378  /// Similar to the above, but gets times of all keys in the channel
379  /// in the specified range.
380  void getKeyTimes(const UT_SuperIntervalR &range,
381  UT_Array<fpreal> &times,
382  bool error_frames_only);
383 
384  // the frames are unique and sorted in a descending order.
385  void getDisabledFrames(UT_Array<int> &frames,
386  int minframe, int maxframe);
387 
388  // EXPRESSIONS
389  CH_Segment *getExpressionSegment( fpreal gtime ) const;
390  const char *getExpression( fpreal gtime ) const;
391  bool changeExpression( fpreal gtime,
392  const char *expr,
393  CH_ExprLanguage language,
394  bool convert_accels );
395  CH_ExprLanguage getCollectionExprLanguage() const;
396  CH_ExprLanguage getExprLanguageAtTime(fpreal time) const;
397  void setExprLanguage(CH_ExprLanguage language);
398  void setExprLanguageAtTime(CH_ExprLanguage language,
399  fpreal time);
400 
401  // If we were to ask for the value of the channel as a string at a
402  // particular time, this function returns what the meaning of that string
403  // would be (either a literal or expression in some language).
404  CH_StringMeaning getStringMeaning(fpreal time) const;
405 
406  // MULTI-SEGMENT MANIPULATION
407  void clearSegments();
408 
409  /// Delete keys in given range
410  void deleteKeys( UT_SuperIntervalR const& range );
411 
412  /// Delete keys at the given key indices.
413  /// @note Must be sorted in ascending order!
414  void deleteKeys(const UT_Array<int> &ascending_sorted_key_indices);
415 
416  void moveFrames(const UT_Array<int> &frames, int amount);
417 
418  bool copyRangeOverwritesKeys(const CH_Channel &src,
419  UT_SuperIntervalR const& range,
420  UT_IntervalR const& to_range);
421  bool copyRangeOverwritesFrames(const CH_Channel &src,
422  UT_SuperIntervalR const& range,
423  UT_IntervalR const& to_range);
424  bool copyRangeOverwrites(const CH_Channel &src,
425  UT_SuperIntervalR const& range,
426  UT_IntervalR const& to_range);
427 
428  void copyRange(const CH_Channel &src,
429  UT_SuperIntervalR const& range,
430  UT_IntervalR const& to_range,
431  bool apply_auto_slope = true);
432 
433  void copyRangeFrames(const CH_Channel &src,
434  const UT_SuperIntervalR &range,
435  const UT_IntervalR &to_range,
436  const UT_Array<int> *frames = nullptr);
437 
438  void deleteRangeFrames(UT_SuperIntervalR const& range,
439  const UT_Array<int> *frames = nullptr);
440 
441  // copyContents copies everything except name and parent
442  void copyContents(const CH_Channel &from);
443  void swapContents( CH_Channel &other );
444  // TODO remove this function:
445  // copy a range of keys. Assumes that we already have keys in the src
446  // channel at those times
447  // another way to do this is: (once we pass UT_SuperIntervalR by value)
448  // ch.clear();
449  // ch.copyRange( src, UT_SuperIntervalR( start, end ), 0.0f );
450  void copyRange(const CH_Channel &src,
451  fpreal global_start, fpreal global_end);
452 
453  // if os is provided, a verbose description of what's happening is printed
454  void snapKeysInRange( const UT_SuperIntervalR &range,
455  SnapType type=SNAP_SNAP,
456  std::ostream *os=nullptr );
457 
458  // ENTIRE CHANNEL MANIPULATION
459  void scroll (fpreal new_start, bool update = true);
460  void stretch(fpreal new_start, fpreal new_end);
461  void reverse(fpreal gstart=0, fpreal gend=0, bool whole_chan = true);
462  // scroll on the y axis (returns success)
463  bool increaseKeyValues( fpreal delta );
464 
465  // DISABLING
466  bool isAllDisabled() const;
467  bool isAllEnabled() const;
468  bool isDisabled(fpreal gtime) const;
469  void disableAll(fpreal gtime);
470  void enableAll();
471  void disable(fpreal gstart, fpreal gend);
472  void enable(fpreal gstart, fpreal gend);
473 
474  // PENDING METHODS
476  bool isPending() const
477  { return myPending; }
478  bool isPending(fpreal gtime) const;
479  bool isPendingLocal(fpreal ltime) const;
480  void clearPending();
481  void updatePending( fpreal gtime );
483  { return globalTime(myPendingEvalTime); }
485  bool isPendingHold() const
486  { return myPendingHold; }
487  void setPendingHold( bool state );
488 
489  // SAVE and LOAD
490  void save(std::ostream &os, bool binary, bool compiled,
491  bool pending_state) const;
492  template <typename FPREAL_TYPE>
493  bool load(UT_IStream &is);
494  void display() const;
495  void displayAsKeys() const;
496 
497  void setDefaultValue(fpreal dv) { myDefValue = dv; }
498  fpreal getDefaultValue() const { return myDefValue; }
499 
501  { myDefString = dv; }
502  const UT_StringHolder &
503  getDefaultString() const { return myDefString; }
504 
505  void setChannelLeftType(CH_ChannelBehavior t);
506  void setChannelRightType(CH_ChannelBehavior t);
507  CH_ChannelBehavior getChannelLeftType() const { return myLeftType; }
508  CH_ChannelBehavior getChannelRightType() const { return myRightType; }
509 
510  static const char *getChannelTypeName(CH_ChannelBehavior type);
511 
512  void setCollection(CH_Collection *chp){ myParent = chp; }
513  const CH_Collection *getCollection() const { return myParent; }
514  CH_Collection *getCollection() { return myParent; }
515 
516  void setIsTemporary( bool temp ) { myIsTemporary = temp; }
517  bool isTemporary() const { return myIsTemporary; }
518 
519  // FLAGS
521  {
522  if( state ) myFlags |= CH_CHANNEL_ACTIVE;
523  else myFlags &= ~CH_CHANNEL_ACTIVE;
524  }
525  bool isChangeActive() const
526  { return (myFlags & CH_CHANNEL_ACTIVE) ? 1 : 0; }
527 
528 
529  bool getLocked() const
530  { return ((myFlags & CH_CHANNEL_LOCKED) != 0); }
531  void setLocked(bool f);
532 
533  int getChanged() const
534  { return (myFlags & CH_CHANNEL_MODIFIED) ? 1 : 0; }
535  void setChanged(bool on,
537  void dirtyExprCache();
538 
539  int canAccess(uint mask) const
540  {
541  if( myParent )
542  return myParent->canAccessChannel(mask, this);
543  else
544  return 1;
545  }
546 
547  // map collection time to channel time...
548  inline fpreal localTime(fpreal t) const { return (t-myStart); }
549 
550  // map channel time to global time...
551  inline fpreal globalTime(fpreal t) const { return t + myStart; }
552 
553  // Returns collection global time...
554  fpreal getStart() const { return myStart; }
555  fpreal getEnd() const { return myStart + myLength;}
556  fpreal getLength() const { return myLength; }
557 
558  // Used to reset the local variables:
559  void unresolveLocalVars(int thread);
560 
561  // Op dependencies
562  void buildOpDependencies(void *ref_id, int thread);
563  void changeOpRef(const char *new_fullpath,
564  const char *old_fullpath,
565  const char *old_cwd,
566  const char *chan_name,
567  const char *old_chan_name,
568  int thread);
569 
570  // Enable or disable value caching in expression segments...
571  void cook(int state);
572 
573  // Load values as keys. Returns the number of samples actually loaded.
574  int setRawValues(fpreal from, fpreal to, fpreal *vals, int nsamples);
575  int setRawValues(fpreal *times, fpreal *vals, int n);
576 
577  // Channel Scope Flag
578  void setScope(bool on_off);
579  bool isScoped() const;
580 
581  // Does this channel have any segments with editable components (eg. value,
582  // slope, acceleration, etc.)?
583  bool isEditable();
584 
585  // Query methods. Used only by CH_Collection
586  fpreal evaluate(fpreal t, bool no_disabling, int thread);
587  void evaluate(fpreal from, fpreal to, fpreal *vals, int nsamples,
588  bool no_disabling, bool use_cache, int thread);
589  fpreal evaluateSegment(CH_Segment *eval, fpreal localtime,
590  bool extend, int thread);
591  void evaluateString(UT_StringHolder &result, fpreal t, int thread);
592  void evaluateStringSegment(UT_StringHolder &result, CH_Segment *eval,
593  fpreal localtime, bool extend,
594  int thread);
595 
596  int findString(const char *str, bool fullword,
597  bool usewildcards) const;
598  int changeString(const char *from, const char *to,
599  bool fullword, bool update /*= true*/,
600  int thread);
601 
602  //
603  // Methods used only in the channel library glue
604  //
605  static inline fpreal getGlueIV(int thread);
606  static inline void getGlueTime(
607  fpreal &t, fpreal &t0, fpreal &t1,
608  fpreal &v0, fpreal &v1, int thread);
609  static inline void getGlueSlope(
610  fpreal *m0, fpreal *m1,
611  fpreal *a0, fpreal *a1, int thread);
612 
613 // Used only by CH_Collection
614  inline const CH_Segment *getEvaluationSegment(int thread) const
615  {
616  return getManager()->evalContext(thread).segment();
617  }
619  {
620  return getManager()->evalContext(thread).segment();
621  }
622  const CH_Segment *getPrevEvaluationSegment(int thread) const;
623  CH_Segment *getPrevEvaluationSegment(int thread);
624  const CH_Segment *getNextEvaluationSegment(int thread) const;
625  CH_Segment *getNextEvaluationSegment(int thread);
626 
627  fpreal getInTime(int thread) const;
628  fpreal getOutTime(int thread) const;
629  fpreal getPrevInTime(int thread) const;
630  fpreal getNextOutTime(int thread) const;
631 
632  // This method will attempt to match the channel name with the pattern,
633  // searching as many parents as necessary regardless of the cwd
634  // eg. tx will match true with tx xform1/tx geo1/xform1/tx
635 
636  int match(const char *pattern) const;
637 
638 
639  // sets all keys to be 'value', and zeros all slopes & accels.
640  void setConstantValue(fpreal value);
641 
642  // sets the data and keys so that the channel approximates the
643  // raw data of samples within given error using cubic interpolation
644  // INPUTS:
645  // data - an array of pairs (time, value) to be fitted.
646  // n_pts - number of elements in data array
647  // error2 - the error to which the channel should approximate data
648  // delete_old_segments - if true, all old segments are cleared before
649  // new ones are generated from data. If false, the segments
650  // that fit the data replace old segments (thus, some
651  // old segments that are outside of the data range will
652  // remain unchanged)
653  // OUTPUTS:
654  // The clip will approximate the curve sampled by data.
655  // The clip will have its start time equal to
656  // the time component of the first pair in the data array,
657  // and the end time equal to the time of the last pair.
658  // RETURNS:
659  // True on success, false if failed.
660  bool fitToPointData( UT_Vector2R *data, int n_pts,
661  bool preserve_extrema,
662  fpreal error2 = 0.01f,
663  bool delete_old_segments = false);
664 
665  // refits the channel data (or portion of it) with cubic interpolation
666  // within given error tolerance. Inserts new keys, etc.
667  // delete_old_segments - if true, all segments are deleted before
668  // refitted range is inserted. Otherwise, old segments outside of the
669  // refitted range are not affected.
670  void refit( fpreal tolerance, bool preserve_extrema );
671  void refit( fpreal tolerance, bool preserve_extrema,
672  fpreal from_gtime, fpreal to_gtime,
673  bool delete_old_segments);
674 
675  /// Overwrites segments and keys in the range
676  /// [start, start + time_delta * (num_keys - 1)]
677  /// @param new_key_values - Array of size num_keys containing the values for
678  /// the new keys
679  /// @param num_keys - Number of keys to set in the new range
680  /// @param global_start - Global start (in time) of the range to replace
681  /// keys in. Must be at or after the global start of this channel
682  /// @param time_delta - Spacing between keys in time
683  /// @param smooth_slopes - Smooth the slopes of the new keys
684  /// @param clear - If true, will first clear all keys and segments
685  /// keys in a partial region
686  /// @param notify - If true, emit a CH_CHANNELS_MAJOR_CHANGE event
687  /// @returns true on success, false if failed
688  bool setKeys(fpreal *new_key_values, int num_keys,
689  fpreal global_start, fpreal time_delta,
690  bool smooth_slopes = true,
691  bool clear = false, bool notify = true);
692 
693  // SEGMENT MANAGEMENT
694  bool isEmpty() const;
695  int getNSegments() const;
696  int getNKeys() const;
697  int getNKeysBefore( fpreal gtime ) const;
698  int getNKeysBeforeOrAt( fpreal gtime ) const;
699 
700  fpreal getKeyTime( unsigned idx ) const;
701 
702  unsigned getSegmentIdx(fpreal local_time) const;
703  CH_Segment *getSegment(unsigned idx) const;
704  CH_Segment *getSegment(fpreal local_time) const;
705 
706  CH_Segment *getNextSegment(unsigned idx) const; // Depends on behavior
707  CH_Segment *getPrevSegment(unsigned idx) const; // Depends on behavior
708 
710  {
711  // empty means no keys in the channel if user delete them
712  // all
713  UT_ASSERT_P( isEmpty() || myEndSegment );
714  return isEmpty()
715  ? nullptr : getSegment( (unsigned)0 );
716  }
718  {
719  // empty means no keys in the channel if user delete them
720  // all
721  UT_ASSERT_P( isEmpty() || myEndSegment );
722 
723  // old behaviour maintained (ie. don't use end segment)
724  return isEmpty()
725  ? nullptr : getSegment( (unsigned)mySegments.entries()-1 );
726  }
727 
728  int64 getMemoryUsage(bool inclusive) const;
729 
730  // The first method takes global time, the second, segment local time.
731  void changeSegLength (CH_Segment *seg, fpreal gtime,
733  bool adjust_and_update = true);
734 
735  bool getHaveCompiledExpressions() const;
736 
737  bool verify();
738  bool verify(bool verify_tied_values);
739 
740  // Snapshots or buffer curves.
741  // Create a deep copy of the channel data for fast modifications and revert workflow.
742  // It's more intuitive than to have to do multiple undo to get back to the previous
743  // keyframes.
744  void saveSnapshot();
745  void undoSnapshot(CH_Channel *previous, bool previous_snapshot_cleared);
746  bool loadSnapshot();
747  bool swapSnapshot();
748  bool clearSnapshot();
749  CH_Channel* getSnapshotChannel();
750  const CH_Channel* getSnapshotChannel() const;
751 
752  /// Smooth the specified auto slopes
753  /// @param slope_flags - bit array indicating which slopes are to be
754  /// smoothed. Each slope (in and out) has a bit and they are arranged
755  /// in left-right order. 0th bit is the in slope of the first seg, so
756  /// for the ith seg, its in slope is at bit 2i and out slope at 2i+1
757  /// @param force - If true, smooths all selected slopes, even if not auto
758  /// @param max_step - If > 0, the maximum amount a slope may
759  /// change from its existing value during this smoothing pass.
760  void smoothAutoSlopesForSegments(
761  UT_RLEBitArray &slope_flags,
762  bool force=false,
763  fpreal max_delta=-1);
764 
765  // Same as above, but you can specify a different max_delta for each slope.
766  // if max_deltas.size()==1, the same max_delta will be used for all slopes.
767  // Otherwise it must be the same length as slope_flags.
768  void smoothAutoSlopesForSegments(
769  UT_RLEBitArray &slope_flags,
770  bool force,
771  UT_Array<fpreal> &max_deltas);
772 
773  void smoothAutoSlopes();
774  /// Smooths slopes of key at time
775  /// Can set up a max step based on delta if > 0
776  /// @param value_changed - true if delta refers to a value change, false
777  /// if delta refers to a time change
778  void smoothAutoSlopes( fpreal global_time, fpreal delta = -1, bool value_changed = true );
779  /// Smooths slopes of keys at both ends of a segment
780  void smoothAutoSlopes( CH_Segment *seg );
781 
782  // Helper function to calculate the max delta for smooth auto slopes.
783  // This is used when moving keys interactively, to prevent slopes from snapping.
784  fpreal smoothAutoSlopesMaxDelta(
785  fpreal global_time,
786  fpreal delta,
787  bool value_changed) const;
788 
789  // Layer Scope Flag
790  void setLayerScope(bool on_off);
791  bool isLayerScoped() const;
792 
793  // Set an array pointer to capture the copyRange actions
794  void setCaptureCopiedKeys(UT_Array<fpreal> *capture_array);
795 
796  // chkey version of putFullKey() doesn't do the same validations as putFullKey()
797  void putChFullKey( fpreal gtime, CH_FullKey const& key, bool accel_ratios = true );
798 
799  fpreal evaluateSegment(CH_Segment &eval, fpreal localtime,
800  bool extend, int thread);
801 
802  fpreal evaluateSegment(CH_Segment &eval, fpreal localtime, int thread);
803  fpreal evaluateSegment(CH_Segment *eval, fpreal localtime, int thread);
804 
805  fpreal evaluateSegmentExtend(CH_Segment *eval, fpreal localtime, int thread);
806  fpreal evaluateSegmentExtend(CH_Segment &eval, fpreal localtime, int thread);
807 
808  fpreal evaluateSegmentSlope(CH_Segment *eval, fpreal localtime, int thread);
809  fpreal evaluateSegmentSlopeApprox(CH_Segment *eval, fpreal localtime, int thread);
810 
811  /// Check if all segment expressions are simple expressions such as
812  /// linear(), bezier(), constant().
813  /// Note that you can still convert to a simple channel even if this returns false,
814  /// but any custom segment expressions will be evaluated as beziers instead.
815  bool isSimpleChannel() const;
816 
817  /// Constructs and returns a simple channel from this channel
818  /// Converts all the segments to CL_SimpleSegments
819  CL_SimpleChannel asSimpleChannel() const;
820  /// Clears this channel and sets it from the given simple channel
821  void fromSimpleChannel(const CL_SimpleChannel &sc);
822 
823 
824  /// clear method that can keep the default values.
825  /// @param clear_defaults - true to clear myDefValue and myDefString.
826  void clear(bool clear_defaults);
827 
828 private:
829 
830  void ensureEndSegmentCreated();
831  void updateEndSegment();
832  void destroyEndSegment();
833 
834  bool isTwoSegChannelTimeDep() const;
835 
836  template <typename T>
837  bool isTimeDependentSlowImpl(int thread) const;
838 
839  // TODO: Remove this. It's abysmally slow, doing a binary search each time
840  bool nextTimeInRange(UT_SuperIntervalR const& range,
841  fpreal &t, bool first) const;
842 
843  friend class CH_BatchModifyScope;
844 
845  void moveKeyInternal(fpreal old_gtime, fpreal new_gtime,
846  CH_BatchModifyScope &scope);
847  // Creates a new key at gtime by splitting, prepending, or appending a
848  // segment as needed.
849  // @param accel_ratio: Whether to preserve acceleration ratios or
850  // raw acceleration values when resizing.
851  // @param skip_key_init: Whether to skip initializing the new key's
852  // values from neighboring segments.
853  void splitSegment(fpreal gtime, bool accel_ratio = true,
854  bool skip_key_init = false);
855  void destroyKeyInternal(unsigned seg_i, CH_BatchModifyScope &scope);
856 
857  // cuts out a portion of a channel. Returns an index at which the cut began
858  int cutOut( fpreal from_gtime, fpreal to_gtime );
859 
860  CH_Segment *appendSegment(CH_Segment *seg);
861 
862  // remove and delete the segment
863  void deleteSegment(unsigned idx);
864 
865  int getNDisableSegments() const
866  { return myDisableSegments.entries(); }
867  CH_Segment *getDisableSegment(unsigned idx) const
868  {
869  return (idx < myDisableSegments.entries()) ?
870  myDisableSegments(idx) : 0;
871  }
872 
873  CH_Segment *getDisableSegmentForLocalTime(fpreal local_time) const;
874  CH_Segment *getPrevDisableSegment(CH_Segment *) const;
875  CH_Segment *getNextDisableSegment(CH_Segment *) const;
876 
877  int getDisableSegmentIndex(fpreal ltime, bool closest_prev) const;
878 
879  CH_Segment *getFirstDisableSegment() const
880  {
881  return (myDisableSegments.entries() > 0) ?
882  myDisableSegments(0) : 0;
883  }
884  CH_Segment *getLastDisableSegment() const
885  {
886  return (myDisableSegments.entries() > 0)
887  ? myDisableSegments(myDisableSegments.entries()-1)
888  : 0;
889  }
890  CH_Segment *appendDisableSegment(CH_Segment *seg);
891 
892  CH_Segment *insertDisableSegment(CH_Segment *seg);
893  CH_Segment *insertDisableSegment(CH_Segment *seg, int idx);
894  CH_Segment *insertDisableSegment(CH_Segment *seg, CH_Segment *before);
895 
896  // Remove but don't delete
897  void removeDisableSegment(CH_Segment *seg);
898  void removeDisableSegment(int idx);
899 
900  void deleteDisableSegment(CH_Segment *);
901  void deleteDisableSegment(int idx);
902 
903  void setPending( bool on_off, fpreal ltime );
904  void updatePendingStateToManager();
905 
906  void deNormalize(fpreal scale);
907 
908  int isCooking() const
909  {
910  return (myFlags & CH_CHANNEL_COOKING) != 0;
911  }
912  void setCooking(bool on_off)
913  {
914  if (on_off) myFlags |= CH_CHANNEL_COOKING;
915  else myFlags &= ~CH_CHANNEL_COOKING;
916  }
917 
918  void adjustSegments(int begin_i, int end_i,
919  CH_CHANGE_TYPE event_type);
920 
921  // Get Segment methods that can return disabled segments.
922  CH_Segment *getFirstSegment(bool no_disabling ) const;
923  CH_Segment *getLastSegment(bool no_disabling ) const;
924  CH_Segment *getEndSegment(bool no_disabling ) const;
925  CH_Segment *getSegment(bool no_disabling, fpreal ltime ) const;
926 
927  enum chGetOrSampleReturn
928  {
929  Sampled, Get, FirstLast
930  };
931  chGetOrSampleReturn getOrSampleKey( fpreal ltime, CH_Key &key, bool accel_ratio, int thread );
932 
933  /// Overwrite all segments and keys for this channel, placing new keys at evenly
934  /// spaced intervals
935  /// This is called by setKeys when the clear parameter is true
936  /// @param new_key_values - Array of size num_keys containing the values for
937  /// the new keys
938  /// @param num_keys - Number of keys to set on the modified curve
939  /// @param new_start - New starting time for the first segment/key
940  /// @param time_delta - Spacing between keys in time
941  /// @returns true on success, false if failed
942  bool setAllKeys(fpreal *new_key_values, int num_keys,
943  fpreal new_start, fpreal time_delta,
944  bool smooth_slopes, bool notify);
945 
946  fpreal transitionSlope(fpreal target, fpreal val, fpreal max_delta);
947 
948  /// Checks if the key at the start of segment seg_idx has one neighbour
949  /// slope which is fixed, and one which is free. If so, applies
950  /// appropriate SDDE smoothing method and returns the number of keys
951  /// affected (0, 1 or 2)
952  int smoothSlopeHalfFixed(int seg_idx, UT_RLEBitArray &flags, fpreal max_delta, bool force);
953 
954 private: // data
955 
956  CH_Collection *myParent; // Who I belong to
957  UT_StringHolder myName;
958  UT_StringHolder myAlias;
959 
960  CH_ChannelBehavior myLeftType; // Type of channel
961  CH_ChannelBehavior myRightType; // Type of channel
962  CH_Segment *myEndSegment;
963 
964  fpreal myDefValue; // Default/Pending value
965  fpreal myStart; // Start time of channel
966  fpreal myLength; // Kept for efficiency (local)
967 
968  UT_StringHolder myDefString; // Default/Pending string value
969 
970  UT_Array<CH_Segment *> mySegments; // Array of segments
971  UT_Array<CH_Segment *> myDisableSegments;
972 
973  fpreal myPendingEvalTime;
974  CH_Channel *mySnapshot;
975  UT_Array<fpreal> *myCaptureCopiedKeys;
976 
977  unsigned char myFlags;
978  bool myPending;
979  bool myPendingHold;
980  bool myScope;
981  bool myLayerScope;
982  bool myIsTemporary;
983  bool myDoingChKey;
984  bool mySnapshotCleared;
985 
986 };
987 
989 
990 inline CH_Segment *
991 CH_Channel::getSegment(unsigned idx) const
992 {
993  if( idx<mySegments.entries() )
994  return mySegments(idx);
995  if( idx==(unsigned)-1 || idx==mySegments.entries() )
996  {
997  UT_ASSERT(myEndSegment || mySegments.entries() == 0);
998  return myEndSegment;
999  }
1000  UT_ASSERT( false );
1001  return nullptr;
1002 }
1003 
1004 inline int
1006 {
1007  return myEndSegment ? 1 + mySegments.entries() : 0;
1008 }
1009 
1010 inline bool
1012 {
1013  return mySegments.isEmpty() && !myEndSegment;
1014 }
1015 
1016 inline int
1018 {
1019  return getNSegments();
1020 }
1021 
1022 inline fpreal
1023 CH_Channel::getKeyTime( unsigned idx ) const
1024 {
1025  CH_Segment *segp;
1026  if( idx == mySegments.entries() )
1027  {
1028  segp = myEndSegment;
1029  UT_ASSERT( segp );
1030  return globalTime( segp->getStart() );
1031  }
1032  segp = getSegment( idx );
1033  UT_ASSERT( segp );
1034  return globalTime( segp->getStart() );
1035 }
1036 
1037 inline bool
1039 {
1040  return getNSegments() == 1;
1041 }
1042 
1043 inline bool
1045 {
1046  // NB: This is actually slightly weaker than PRM_Float::isRotationParm()
1047  return myName == "rx" || myName == "ry" || myName == "rz";
1048 }
1049 
1050 
1051 /// Const iterator over an interval
1053 {
1054 public:
1056  : myChannel(nullptr)
1057  , myI(-1)
1058  , myTol(0.0)
1059  {
1060  }
1061 
1063  {
1064  ++myI;
1065  return *this;
1066  }
1068  {
1069  --myI;
1070  return *this;
1071  }
1072 
1073  bool atEnd() const
1074  {
1075  if (myI >= myChannel->getNSegments())
1076  return true;
1077  fpreal lt = localTime();
1078  return !(myRange.myMaxInclusive ?
1079  SYSisLessOrEqual(lt, myRange.max, myTol)
1080  : SYSisLess(lt, myRange.max, myTol));
1081  }
1082  bool atPre() const
1083  {
1084  if (myI < 0)
1085  return true;
1086  fpreal lt = localTime();
1087  return !(myRange.myMinInclusive ?
1088  SYSisGreaterOrEqual(lt, myRange.min, myTol)
1089  : SYSisGreater(lt, myRange.min, myTol));
1090  }
1091 
1092  unsigned index() const
1093  {
1094  return (unsigned)myI;
1095  }
1096 
1097  const CH_Segment &segment() const
1098  {
1099  return *(myChannel->getSegment((unsigned)myI));
1100  }
1101 
1102  // Local time at start of segment
1104  {
1105  return myChannel->getSegment((unsigned)myI)->getStart();
1106  }
1107 
1108  fpreal operator*() const { return myChannel->globalTime(localTime()); }
1109 
1110 protected:
1112  const CH_Channel &ch, const UT_SuperIntervalR &range,
1113  const bool ascending)
1114  : myChannel(&ch)
1115  , myRange(range)
1116  , myTol(ch.getTolerance())
1117  {
1118  myRange.min = ch.localTime(myRange.min);
1119  myRange.max = ch.localTime(myRange.max);
1120  UT_ASSERT(myRange.min <= myRange.max);
1121  if (ascending)
1122  {
1123  // If myRange.min is less than the first segment's start time, then
1124  // the first segment is returned by getSegmentIdx().
1125  myI = ch.getSegmentIdx(myRange.min);
1126  CH_Segment *seg = ch.getSegment((unsigned)myI);
1127  if (seg)
1128  {
1129  fpreal lt = seg->getStart();
1130  if (range.myMinInclusive)
1131  {
1132  if (SYSisLess(lt, myRange.min, myTol))
1133  ++myI;
1134  }
1135  else
1136  {
1137  if (SYSisLessOrEqual(lt, myRange.min, myTol))
1138  ++myI;
1139  }
1140  }
1141  else
1142  {
1143  myI = ch.getNSegments();
1144  }
1145  UT_ASSERT(atEnd() || myRange.contains(localTime(), myTol));
1146  }
1147  else // descending
1148  {
1149  myI = ch.getSegmentIdx(myRange.max);
1150  CH_Segment *seg = ch.getSegment((unsigned)myI);
1151  if (seg)
1152  {
1153  fpreal lt = seg->getStart();
1154  if (range.myMaxInclusive)
1155  {
1156  if (SYSisGreater(lt, myRange.max, myTol))
1157  --myI;
1158  }
1159  else
1160  {
1161  if (SYSisGreaterOrEqual(lt, myRange.max, myTol))
1162  --myI;
1163  }
1164  }
1165  else
1166  {
1167  myI = -1;
1168  }
1169  UT_ASSERT(atPre() || myRange.contains(localTime(), myTol));
1170  }
1171  }
1172 
1173 private:
1174  const CH_Channel * myChannel;
1175  UT_SuperIntervalR myRange;
1176  int myI;
1177  fpreal myTol;
1178 
1179  friend class CH_Channel;
1180 };
1181 
1182 /// Iterator over an interval
1184 {
1185 public:
1187  : ConstIntervalIter()
1188  {
1189  }
1190 
1192  {
1193  return const_cast<CH_Segment &>(ConstIntervalIter::segment());
1194  }
1195 
1197  {
1199  return *this;
1200  }
1202  {
1204  return *this;
1205  }
1206 
1207 protected:
1209  const CH_Channel &ch, const UT_SuperIntervalR &range, bool reverse)
1210  : ConstIntervalIter(ch, range, reverse)
1211  {
1212  }
1213 
1214 private:
1215 
1216  friend class CH_Channel;
1217 };
1218 
1221  const UT_SuperIntervalR & range, const bool ascending) const
1222 {
1223  return IntervalIter(*this, range, ascending);
1224 }
1227  const UT_SuperIntervalR & range, const bool ascending) const
1228 {
1229  return ConstIntervalIter(*this, range, ascending);
1230 }
1231 
1232 // this will move attempted_dt towards accepted_dt so that:
1233 // keys[i]+attempted_dt does not land on another key
1234 // attempted_dt stays on the same side of accepted_dt as it started
1235 // (so that if you're moving one way, they don't snap backwards before
1236 // where they started)
1237 // if snap_to_frame, attempted_dt+base_time will land on a frame
1238 CH_API extern void
1239 CHfindMoveKeysDelta(const CH_Channel *chp, bool snap_to_frame, fpreal base_time,
1240  const UT_Array<fpreal> &sorted_orig_keys,
1241  fpreal accepted_dt, fpreal &attempted_dt);
1242 
1243 CH_API extern void
1244 CHmoveKeysWithDelta(CH_Channel *chp, const UT_Array<fpreal> &orig_keys,
1245  fpreal old_accepted_dt, fpreal new_accepted_dt);
1246 
1247 // Move a list of keys using a list of time offset and value offsets.
1248 CH_API extern void
1249 CHmoveKeysWithDeltas(CH_Channel *chp, const UT_Array<fpreal> &orig_keys,
1250  const UT_Array<fpreal> &time_offsets,
1251  const UT_Array<fpreal> &value_offsets);
1252 
1253 ///////////////////////////////////////////////////////////////////////////////
1254 //
1255 // Inline Implementations
1256 //
1257 
1258 /*static*/ inline fpreal
1260 {
1261  const CH_EvalContext & ctx = CHgetManager()->evalContext(thread);
1262  const CH_Channel * eval_channel = ctx.channel();
1263  const CH_Segment * segp = ctx.segment();
1264 
1265  if (segp)
1266  {
1267  if (eval_channel->isPending(ctx.time()))
1268  return eval_channel->getDefaultValue();
1269  else
1270  return segp->getInValue();
1271  }
1272 
1273  return 0.0f;
1274 }
1275 
1276 /*static*/ inline void
1278  fpreal &v0, fpreal &v1, int thread)
1279 {
1280  CH_Manager & mgr = *CHgetManager();
1281  CH_EvalContext & ctx = mgr.evalContext(thread);
1282  const CH_Channel * eval_channel = ctx.channel();
1283  const CH_Segment * segp = ctx.segment();
1284 
1285  if (eval_channel)
1286  {
1287  t = eval_channel->localTime(ctx.time());
1288  if (segp)
1289  {
1290  t0 = segp->getStart();
1291  t1 = segp->getEnd();
1292  if( eval_channel->isPendingLocal(t) )
1293  {
1294  v0 = v1 = eval_channel->getDefaultValue();
1295  t0 = t1 = t;
1296  }
1297  else
1298  {
1299  v0 = segp->getInValue();
1300  v1 = segp->getOutValue();
1301  if( segp->isEndSegment() )
1302  {
1303  // Since our segment length is zero, we want fake it so
1304  // that it uses either the in or out values because most
1305  // existing expression functions will take the average of
1306  // them when encountering a zero length segement.
1307  // NB: the in/out values are swapped on end segments.
1308  if (SYSisGreaterOrEqual(t, t0, mgr.getTolerance()))
1309  v1 = v0;
1310  else
1311  v0 = v1;
1312  }
1313  }
1314  }
1315  else
1316  {
1317  t0 = eval_channel->getStart();
1318  t1 = eval_channel->getEnd();
1319  v0 = v1 = 0;
1320  }
1321  }
1322  else
1323  {
1324  t = 0.0f;
1325  t0 = 0.0f;
1326  t1 = 0.0f;
1327  v0 = 0.0f;
1328  v1 = 0.0f;
1329  }
1330 }
1331 
1332 /*static*/ inline void
1334  int thread)
1335 {
1336  CH_EvalContext & ctx = CHgetManager()->evalContext(thread);
1337  const CH_Segment * segp = ctx.segment();
1338 
1339  if (segp)
1340  {
1341  if (m0) *m0 = segp->getInSlope();
1342  if (m1) *m1 = segp->getOutSlope();
1343  if (a0) *a0 = segp->getInAccel();
1344  if (a1) *a1 = segp->getOutAccel();
1345  }
1346  else
1347  {
1348  if (m0) *m0 = 0.0f;
1349  if (m1) *m1 = 0.0f;
1350  if (a0) *a0 = 0.0f;
1351  if (a1) *a1 = 0.0f;
1352  }
1353 }
1354 
1355 // this returns if the channel is time dependent without evaluating
1356 // the channel
1357 inline bool
1359 {
1360  const int nsegs = getNSegments();
1361 
1362  if (nsegs == 0)
1363  return false;
1364 
1365  if (nsegs == 1)
1366  return getSegment(0U)->isTimeDependent();
1367 
1368  if (nsegs == 2)
1369  return isTwoSegChannelTimeDep();
1370 
1371  // Else, assume time dependent when more than 1 segment
1372  UT_ASSERT_P(nsegs > 1);
1373  return true;
1374 }
1375 
1376 
1377 // UTformat support.
1378 static inline size_t
1379 UTformatBuffer(char *buffer, size_t buffer_size, const CH_Channel &v)
1380 {
1381  UT_String s;
1382  v.getFullPath(s);
1383  if (!buffer)
1384  return s.length();
1385  else
1386  {
1387  size_t len = std::min(size_t(s.length()), buffer_size);
1388  ::memcpy(buffer, s.c_str(), len);
1389  return len;
1390  }
1391 }
1392 
1393 #endif // __CH_Channel_h__
const UT_StringHolder & getAlias() const
Definition: CH_Channel.h:202
Iterator over an interval.
Definition: CH_Channel.h:1183
GLint first
Definition: glcorearb.h:405
CH_ExprLanguage myRevExprLanguage
Definition: CH_Channel.h:126
fpreal localTime(fpreal t) const
Definition: CH_Channel.h:548
CE_API bool evaluate(const CE_OSDRefinement &topo, const CE_OSDEvaluator &eval, const cl::Buffer &coarse, const CE_OSDPatchCoords &patch_coords, const CE_FloatArray *refined_data, cl::Buffer &out, cl::Buffer *du, cl::Buffer *dv)
CH_ChannelBehavior getChannelRightType() const
Definition: CH_Channel.h:508
GLbitfield flags
Definition: glcorearb.h:1596
unsigned getSegmentIdx(fpreal local_time) const
bool myUseExpression
Definition: CH_Channel.h:105
GLenum GLint * range
Definition: glcorearb.h:1925
bool myUseRevExpression
Definition: CH_Channel.h:124
static void getGlueTime(fpreal &t, fpreal &t0, fpreal &t1, fpreal &v0, fpreal &v1, int thread)
Definition: CH_Channel.h:1277
const UT_StringHolder & getDefaultString() const
Definition: CH_Channel.h:503
CH_Segment * getEvaluationSegment(int thread)
Definition: CH_Channel.h:618
bool isEndSegment() const
Definition: CH_Segment.h:302
CH_ExprLanguage
IntervalIter intervalIter(const UT_SuperIntervalR &range, const bool ascending=true) const
Definition: CH_Channel.h:1220
void
Definition: png.h:1083
GLint left
Definition: glcorearb.h:2005
CH_Key()
Definition: CH_Channel.h:63
Const iterator over an interval.
Definition: CH_Channel.h:1052
CH_StringMeaning
GT_API const UT_StringHolder time
const GLdouble * v
Definition: glcorearb.h:837
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
GLsizei const GLfloat * value
Definition: glcorearb.h:824
fpreal globalTime(fpreal t) const
Definition: CH_Channel.h:551
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
void getFullPath(UT_StringHolder &path) const
Definition: CH_Channel.h:214
bool isRotationChannel() const
Definition: CH_Channel.h:1044
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
bool myEvaluatedSlopes
Definition: CH_Channel.h:60
const CH_Segment * segment() const
GLdouble right
Definition: glad.h:2817
bool isTemporary() const
Definition: CH_Channel.h:517
bool isEmpty() const
Definition: CH_Channel.h:1011
CH_API void CHmoveKeysWithDelta(CH_Channel *chp, const UT_Array< fpreal > &orig_keys, fpreal old_accepted_dt, fpreal new_accepted_dt)
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
fpreal getEnd() const
Definition: CH_Channel.h:555
GLdouble s
Definition: glad.h:3009
void swap(T &lhs, T &rhs)
Definition: pugixml.cpp:7440
void setIsTemporary(bool temp)
Definition: CH_Channel.h:516
PUGI__FN void reverse(I begin, I end)
Definition: pugixml.cpp:7458
fpreal getInValue() const
Definition: CH_Segment.h:306
CH_FullKey & operator=(CH_FullKey const &other)
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
const CH_Segment & segment() const
Definition: CH_Channel.h:1097
**But if you need a result
Definition: thread.h:622
CH_Segment & segment() const
Definition: CH_Channel.h:1191
GLuint buffer
Definition: glcorearb.h:660
fpreal getInSlope() const
Definition: CH_Segment.h:308
const CH_EvalContext & evalContext(int thread) const
Definition: CH_Manager.h:1452
fpreal getOutValue() const
Definition: CH_Segment.h:307
const char * c_str() const
Definition: UT_String.h:524
bool isChangeActive() const
Definition: CH_Channel.h:525
class CH_API IntervalIter
Definition: CH_Channel.h:268
bool hasOnlyOneSegment() const
Definition: CH_Channel.h:1038
unsigned length() const
Return length of string.
Definition: UT_String.h:568
void putKey(fpreal gtime, CH_Key const &key, bool accel_ratios=true, bool apply_auto_slope=true)
Definition: CH_Channel.h:314
bool isTimeDependent() const
Definition: CH_Segment.h:260
int canAccess(uint mask) const
Definition: CH_Channel.h:539
fpreal64 time() const
static fpreal getGlueIV(int thread)
Definition: CH_Channel.h:1259
CH_API void CHmoveKeysWithDeltas(CH_Channel *chp, const UT_Array< fpreal > &orig_keys, const UT_Array< fpreal > &time_offsets, const UT_Array< fpreal > &value_offsets)
IntervalIter & operator--()
Definition: CH_Channel.h:1201
bool isPendingLocal(fpreal ltime) const
fpreal getDefaultValue() const
Definition: CH_Channel.h:498
GA_API const UT_StringHolder scale
class CH_API ConstIntervalIter
Definition: CH_Channel.h:267
ConstIntervalIter constIntervalIter(const UT_SuperIntervalR &range, const bool ascending=true) const
Definition: CH_Channel.h:1226
GLdouble n
Definition: glcorearb.h:2008
ConstIntervalIter & operator--()
Definition: CH_Channel.h:1067
GLfloat f
Definition: glcorearb.h:1926
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
UT_String myRevExpression
Definition: CH_Channel.h:125
CH_CHANGE_TYPE
CH_Manager * CHgetManager()
Definition: CH_Manager.h:2151
ConstIntervalIter & operator++()
Definition: CH_Channel.h:1062
void setCollection(CH_Collection *chp)
Definition: CH_Channel.h:512
const CH_Segment * getEvaluationSegment(int thread) const
Definition: CH_Channel.h:614
fpreal getLength() const
Definition: CH_Channel.h:556
CH_API void CHfindMoveKeysDelta(const CH_Channel *chp, bool snap_to_frame, fpreal base_time, const UT_Array< fpreal > &sorted_orig_keys, fpreal accepted_dt, fpreal &attempted_dt)
CH_ChannelBehavior
Definition: CH_Types.h:58
PXL_API const char * getName(const ColorSpace *space)
Return the name of the color space.
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:164
constexpr auto set(type rhs) -> int
Definition: core.h:610
fpreal getStart() const
Definition: CH_Segment.h:345
bool getLocked() const
Definition: CH_Channel.h:529
UT_String myExpression
Definition: CH_Channel.h:106
void display() const
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
fpreal getKeyTime(unsigned idx) const
Definition: CH_Channel.h:1023
fpreal myTimeValue
Definition: CH_Channel.h:59
void setDefaultValue(fpreal dv)
Definition: CH_Channel.h:497
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
GLint GLuint mask
Definition: glcorearb.h:124
IntervalIter(const CH_Channel &ch, const UT_SuperIntervalR &range, bool reverse)
Definition: CH_Channel.h:1208
CH_Segment * getLastSegment() const
Definition: CH_Channel.h:717
long long int64
Definition: SYS_Types.h:116
GLenum target
Definition: glcorearb.h:1667
HUSD_API bool eval(VtValue &val, T &ret_val)
GLuint const GLchar * name
Definition: glcorearb.h:786
CH_Segment * getSegment(unsigned idx) const
Definition: CH_Channel.h:991
GLushort pattern
Definition: glad.h:2583
void reverse(fpreal gstart=0, fpreal gend=0, bool whole_chan=true)
GLdouble t
Definition: glad.h:2397
void setName(const UT_StringHolder &s)
Definition: CH_Channel.h:220
GLfloat v0
Definition: glcorearb.h:816
IntervalIter & operator++()
Definition: CH_Channel.h:1196
void setChangeActive(int state)
Definition: CH_Channel.h:520
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:669
SYS_FORCE_INLINE bool isPending() const
Definition: CH_Channel.h:476
CH_Collection * getCollection()
Definition: CH_Channel.h:514
CH_ExprLanguage myExprLanguage
Definition: CH_Channel.h:107
**Note that the tasks the is the thread number *for the or if it s being executed by a non pool thread(this *can happen in cases where the whole pool is occupied and the calling *thread contributes to running the work load).**Thread pool.Have fun
fpreal getStart() const
Definition: CH_Channel.h:554
void stretch(fpreal xscale, fpreal yscale, bool accel_ratio)
CH_ValueTypes
Definition: CH_Types.h:113
int getNSegments() const
Definition: CH_Channel.h:1005
SIM_API const UT_StringHolder force
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:587
void reverse()
CH_Segment * getFirstSegment() const
Definition: CH_Channel.h:709
fpreal64 fpreal
Definition: SYS_Types.h:283
CH_Manager * getManager() const
Definition: CH_Channel.h:223
#define CH_API
Definition: CH_API.h:10
void setAlias(const UT_StringHolder &s)
Definition: CH_Channel.h:221
LeafData & operator=(const LeafData &)=delete
void display() const
const CH_Collection * getCollection() const
Definition: CH_Channel.h:513
GLfloat GLfloat v1
Definition: glcorearb.h:817
GLuint GLfloat * val
Definition: glcorearb.h:1608
bool isTimeDependent() const
Definition: CH_Channel.h:1358
fpreal getOutSlope() const
Definition: CH_Segment.h:309
void setDefaultString(const UT_StringHolder &dv)
Definition: CH_Channel.h:500
int getChanged() const
Definition: CH_Channel.h:533
fpreal getPendingEvalTime() const
Definition: CH_Channel.h:482
CH_SegmentScale
Definition: CH_Types.h:107
#define UT_SWAPPER_CLASS(T)
Definition: UT_Swap.h:60
fpreal getTolerance() const
Definition: CH_Channel.h:225
fpreal getOutAccel() const
Definition: CH_Segment.h:311
CH_Segment * putFullKey(fpreal gtime, CH_FullKey const &key, bool accel_ratios=true, bool apply_auto_slope=true)
Definition: CH_Channel.h:319
fpreal getInAccel() const
Definition: CH_Segment.h:310
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
int getNKeys() const
Definition: CH_Channel.h:1017
void getFullPath(UT_String &path) const
Definition: CH_Channel.h:210
static void getGlueSlope(fpreal *m0, fpreal *m1, fpreal *a0, fpreal *a1, int thread)
Definition: CH_Channel.h:1333
CH_ChannelBehavior getChannelLeftType() const
Definition: CH_Channel.h:507
ConstIntervalIter(const CH_Channel &ch, const UT_SuperIntervalR &range, const bool ascending)
Definition: CH_Channel.h:1111
SYS_FORCE_INLINE bool isPendingHold() const
Definition: CH_Channel.h:485
unsigned int uint
Definition: SYS_Types.h:45
state
Definition: core.h:2289
bool contains(T arg, T tol=T(SYS_FTOLERANCE)) const
CH_GetKeyExtend
Definition: CH_Types.h:92
fpreal getTolerance() const
Definition: CH_Manager.h:1234
FMT_BEGIN_EXPORT std::tm localtime(std::time_t time)
Definition: chrono.h:444
Definition: format.h:1821
const CH_Channel * channel() const
fpreal getEnd() const
Definition: CH_Segment.h:346
bool isEmpty() const
Returns true iff there are no occupied elements in the array.
Definition: UT_Array.h:671
GLenum src
Definition: glcorearb.h:1793