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