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