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