HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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_EventManager.h"
18 #include "CH_Manager.h"
19 #include "CH_Segment.h"
20 #include "CH_Types.h"
21 
22 #include <UT/UT_Defines.h>
23 #include <UT/UT_IntArray.h>
24 #include <UT/UT_IStream.h>
25 #include <UT/UT_String.h>
26 #include <UT/UT_SuperInterval.h>
27 #include <UT/UT_Swap.h>
28 #include <UT/UT_ValArray.h>
29 #include <UT/UT_VectorTypes.h>
30 
31 #include <SYS/SYS_Types.h>
32 #include <iosfwd>
33 #include <stddef.h>
34 
35 
36 CH_API extern char
38 
39 typedef enum {
40  CH_CHANNEL_DEFAULT, // Channel is default value beyond defined range
41  CH_CHANNEL_HOLD, // Channel is start/end value before/after
42  CH_CHANNEL_CYCLE, // Channel wraps to defined range
43  CH_CHANNEL_EXTEND, // Channel function continues outside start/end
44  CH_CHANNEL_SLOPE, // Channel extends at start/end slope
45  CH_CHANNEL_CYCLEOFF, // Channel warps tot defined range and offsets.
46  CH_CHANNEL_OSCILLATE, // Channel warps tot defined range and offsets.
49 
50 
51 // NB: This enum only has 8 bits.
52 // Do not change these values as they get saved.
53 typedef enum {
57  CH_CACHE_ENABLED = 0x04, // no longer used!
58  CH_CHANNEL_SPARE = 0x08, // no longer used!
60 
63 
65 
66  // flags to save
68 
69  CH_CHANNEL_FLAG_MASK = 0xFF // sentinel: we've only got 8 bits
71 
72 // Enum for the CH_Channel::getKey and getFullKey methods
73 typedef enum {
74  CH_GETKEY_EXTEND_NONE, // Don't extend the channel cycle.
75  CH_GETKEY_EXTEND_DEFAULT, // Extend the channel extrapolation, and returns keys in the middle.
76  CH_GETKEY_EXTEND_BOUNDARY, // Extend the channel extrapolation, but give a hint that the key is the last or the first.
78 
79 
80 class CH_Segment;
81 class CH_Manager;
82 class CH_SegmentRef;
83 
84 
86 {
87 public:
89  bool myVValid[ CH_NUM_VALUES ];
90  bool myVTied[ CH_NUM_VALUES ];
91  bool myVAuto[ CH_NUM_VALUES ];
92 };
93 
95 {
96 public:
99  CH_HalfKey k[2];
100 
101  CH_Key() { clear(); }
102 
103  void display() const;
104 
105  void clear();
106 
107  // direction is one of -1, 0, 1
108  // -1 = tie using left value
109  // 0 = tie averaging both
110  // 1 = tie using right value
111  void tie( int direction, CH_ValueTypes t );
112 
113  void tie( int direction );
114 
115  void setAuto( CH_ValueTypes t );
116 
117  void set( CH_ValueTypes t, fpreal value );
118  bool isSet( CH_ValueTypes t ) const;
119 
120  void complete();
121 
122  void get( CH_Segment *left_seg, CH_Segment *right_seg,
123  bool accel_ratio = true );
124 
125  void put( CH_Segment *left_seg, CH_Segment *right_seg,
126  bool accel_ratio = true ) const;
127 
128  void stretch( fpreal xscale, fpreal yscale, bool accel_ratio );
129 
130  void changeAccelsToRatios( fpreal left_seg_len, fpreal right_seg_len );
131 
132  void reverse();
133 
134  void opscript( std::ostream &os, bool use_time,
135  bool only_valid=true ) const;
136 
137  bool verify( bool check_tied_slopes=true ) const;
138 };
139 
140 class CH_API CH_FullKey: public CH_Key
141 {
142 public:
146 
148  {
149  myUseExpression = false;
150  myExprLanguage = CH_OLD_EXPR_LANGUAGE;
151  }
152 
153  CH_FullKey( CH_FullKey const& other );
154  CH_FullKey &operator=( CH_FullKey const& other );
155 
156  void display() const;
157 };
158 
160 {
161 public:
165 
167  {
168  myUseRevExpression = false;
169  myRevExprLanguage = CH_OLD_EXPR_LANGUAGE;
170  }
171 
172  CH_ReversibleKey( CH_ReversibleKey const& other );
174 
175  void display() const;
176 
177  void stretch( fpreal xscale, fpreal yscale, bool accel_ratio );
178 
179  void reverse();
180 };
181 
182 //
183 // Iterator for going through .chn and .bchn files,
184 // channel by channel, until the end of channels for current collection is
185 // reached. The iterator can be restarted by calling begin() again.
186 //
188 {
189 // After using begin or nextChannel, the position in the stream
190 // will be proper for using CH_Channel::load or CH_Collection::loadChannelRange
191 public:
193  bool begin(UT_String &name, const UT_String *path=NULL);
194  bool end() { return noMoreChannels; }
195  bool nextChannel(UT_String &name);
196  int getLastError() { return lastError; }
197 
198 private:
199  UT_IStream *curr_is;
200  UT_String curr_coll;
201  int is_binary;
202  int lastError;
203  bool noMoreChannels;
204 };
205 
206 
208 {
209 public:
210  typedef enum
211  {
215  SNAP_REPLACE_DOUBLE
216  } SnapType;
217 
218  CH_Channel(CH_Collection *dad, const char *name, fpreal default_value = 0,
219  const char *default_string = 0);
220  CH_Channel(CH_Collection *dad, const CH_Channel &from);
221  ~CH_Channel();
222 
223  void initializeFirstSegment(const char *expr,
224  CH_ExprLanguage language);
225 
226  // Initialize parents of mySegments and myDisableSegments to this
227  void initializeSegmentParents();
228 
229  // UTILITIES
230  void clear();
231  void swap( CH_Channel &other );
232 
233  const UT_String &getName(void) const { return myName; }
234  const UT_String &getAlias(void) const;
235  void getFullPath( UT_String &path ) const;
236 
237  // Used only by CH_Collection
238  void setName(const char *s) { myName.harden(s); }
239  void setAlias(const char *s) { myAlias.harden(s); }
240 
241  CH_Manager *getManager() const { return myParent->getManager(); }
242 
244  { return getManager()->getTolerance(); }
245 
246  // This returns if the channel is time dependent without evaluating
247  // the channel.
248  bool isTimeDependent() const;
249 
250  // These return if the channel is time dependent and will catch more cases
251  // than isTimeDependent() by evaluating the channel.
252  bool isTimeDependentSlow(int thread) const;
253  bool isStringTimeDependentSlow(int thread) const;
254 
255  bool hasNonIntegerKeys() const;
256  bool isDataDependent(fpreal gtime) const;
257 
258  // are we using a zero-length segment to represent one key?
259  bool hasOnlyOneSegment() const;
260 
261  bool isRotationChannel() const;
262 
263  // KEYS
264  bool getSurroundingSegs( fpreal gtime,
265  CH_Segment *&left, CH_Segment *&right ) const;
266 
267  CH_Segment *getSegmentAfterKey( fpreal gtime ) const;
268 
269  // isAtKey returns true if the channel is considered modifiable at
270  // the given time. This means there's either no segment there or the
271  // segment is constant or there's a timemark there (segment start|end).
272  bool isAtKey(fpreal gtime) const;
273 
274  // isAtHardKey returns true only if there's a timemark (segment start
275  // or end) at the given time.
276  bool isAtHardKey(fpreal gtime) const;
277  bool isAtHardKeyframe(int frame) const;
278 
279  fpreal findKey(fpreal gtime, fpreal direction) const;
280  int findKeyframe(int frame, int direction) const;
281 
284 
285  /// Return an iterator for keys within the given interval. If ascending is
286  /// false, then the iterator is initialized at the end of the range
287  /// instead of at the beginning of the range.
288  /// @{
289  IntervalIter intervalIter(
290  const UT_SuperIntervalR & range,
291  const bool ascending=true) const;
292  ConstIntervalIter constIntervalIter(
293  const UT_SuperIntervalR & range,
294  const bool ascending=true) const;
295  /// @}
296 
297  // sample functions evaluate the channel to find values
298  // getKey functions only evaluate if the time is not already at a hard key
299  void sampleValueSlope( CH_Segment *seg, fpreal gtime,
300  int thread, fpreal &v, fpreal &s );
301  bool sampleVSA( CH_Segment *seg, fpreal gtime, int thread,
302  fpreal &v, fpreal &s, fpreal a[2] );
303  void sampleKey( CH_Segment *seg, fpreal gtime, int thread,
304  CH_Key &key );
305  bool getKey( fpreal gtime, CH_Key &key,
306  bool accel_ratios = true,
308  bool getFullKey( fpreal gtime, CH_FullKey &key,
309  bool reverse = false,
310  bool accel_ratios = true,
312  bool getReversibleKey( fpreal gtime, CH_ReversibleKey &key );
313 
314  void putKey( fpreal gtime, CH_Key const& key,
315  bool accel_ratios = true );
316  void putFullKey( fpreal gtime, CH_FullKey const& key,
317  bool accel_ratios = true );
318 
319  void transferKey(fpreal to_time,
320  CH_Channel *from_chp, fpreal from_time);
321 
322  void applyPendingToKey( CH_Key &key, fpreal gtime );
323  void applyDefaultSlopeToKey( CH_Key &key );
324 
325  /// Insert key at given time
326  void insertKeyFrame(fpreal global_t, bool use_auto_slope_pref=true);
327 
328  /// Delete key at given time
329  void destroyKeyFrame(fpreal global_t);
330 
331  /// Move key from old time to new time. Requires that a key exists at
332  /// old_gtime and that there is no key at new_gtime.
333  void moveKeyFrame( fpreal old_gtime, fpreal new_gtime );
334 
335  void saveKeyFrameForUndo( fpreal global_t );
336 
337  // this function is a bit confusing
338  // Sets the in/out values for a segment to the val at a time specified
339  //The method returns 0 if it was successfull,
340  // -1 if there was no key at the time specified
341  // set_pending = if true,the pending value is set to val, unless commit_keys
342  // is true, and gtime falls on a key frame.
343  // commit_keys = if true and gtime falls on a key frame, the keyed value
344  // for that frame is set to val, pending is cleared if
345  // set_pending is true
346  int setKeyValue(fpreal val, fpreal gtime,
347  bool set_pending = false,
348  bool commit_keys = true,
349  bool propagate = true);
350  int setKeyString(const UT_String &str, fpreal gtime,
351  bool set_pending = false,
352  bool commit_keys = true,
353  bool propagate = true);
354  int setKeyString(const UT_String &str, fpreal gtime,
355  CH_ExprLanguage language,
356  bool set_pending = false,
357  bool commit_keys = true,
358  bool propagate = true);
359  void holdValue( fpreal gtime, int thread );
360 
361  // utility functions for getting keyframe numbers:
362  // they return array of keyframes in the channel
363  // the frames are unique and sorted in a ascending order.
364  void getKeyFrames( UT_SuperIntervalR const& range,
365  UT_IntArray &frames,
366  bool error_frames_only );
367 
368  /// Similar to the above, but gets times of all keys in the channel
369  /// in the specified range.
370  void getKeyTimes( UT_SuperIntervalR const& range,
371  UT_FprealArray &times,
372  bool error_frames_only );
373 
374  // the frames are unique and sorted in a descending order.
375  void getDisabledFrames(UT_IntArray &frames,
376  int minframe, int maxframe);
377 
378  // EXPRESSIONS
379  CH_Segment *getExpressionSegment( fpreal gtime ) const;
380  const char *getExpression( fpreal gtime ) const;
381  bool changeExpression( fpreal gtime,
382  const char *expr,
383  CH_ExprLanguage language,
384  bool convert_accels );
385  CH_ExprLanguage getCollectionExprLanguage() const;
386  CH_ExprLanguage getExprLanguageAtTime(fpreal time) const;
387  void setExprLanguage(CH_ExprLanguage language);
388  void setExprLanguageAtTime(CH_ExprLanguage language,
389  fpreal time);
390 
391  // If we were to ask for the value of the channel as a string at a
392  // particular time, this function returns what the meaning of that string
393  // would be (either a literal or expression in some language).
394  CH_StringMeaning getStringMeaning(fpreal time) const;
395 
396  // MULTI-SEGMENT MANIPULATION
397  void clearSegments();
398 
399  /// Delete keys in given range
400  void deleteKeys( UT_SuperIntervalR const& range );
401 
402  /// Delete keys at the given key indices.
403  /// @note Must be sorted in ascending order!
404  void deleteKeys(const UT_IntArray &ascending_sorted_key_indices);
405 
406  void moveFrames(const UT_IntArray &frames, int amount);
407 
408  bool copyRangeOverwritesKeys(const CH_Channel &src,
409  UT_SuperIntervalR const& range,
410  UT_IntervalR const& to_range);
411  bool copyRangeOverwritesFrames(const CH_Channel &src,
412  UT_SuperIntervalR const& range,
413  UT_IntervalR const& to_range);
414  bool copyRangeOverwrites(const CH_Channel &src,
415  UT_SuperIntervalR const& range,
416  UT_IntervalR const& to_range);
417 
418  void copyRange(const CH_Channel &src,
419  UT_SuperIntervalR const& range,
420  UT_IntervalR const& to_range);
421 
422  void copyRangeFrames(const CH_Channel &src,
423  UT_SuperIntervalR const& range,
424  UT_IntervalR const& to_range,
425  const UT_IntArray * frames = NULL);
426 
427  void deleteRangeFrames(UT_SuperIntervalR const& range,
428  const UT_IntArray * frames = NULL);
429 
430  // copyContents copies everything except name and parent
431  void copyContents(const CH_Channel &from);
432  void swapContents( CH_Channel &other );
433  // TODO remove this function:
434  // copy a range of keys. Assumes that we already have keys in the src
435  // channel at those times
436  // another way to do this is: (once we pass UT_SuperIntervalR by value)
437  // ch.clear();
438  // ch.copyRange( src, UT_SuperIntervalR( start, end ), 0.0f );
439  void copyRange(const CH_Channel &src,
440  fpreal global_start, fpreal global_end);
441 
442  // if os is provided, a verbose description of what's happening is printed
443  void snapKeysInRange( const UT_SuperIntervalR &range,
444  SnapType type=SNAP_SNAP,
445  std::ostream *os=0 );
446 
447  // ENTIRE CHANNEL MANIPULATION
448  void scroll (fpreal newStart, bool update = true);
449  void stretch(fpreal newStart, fpreal newEnd);
450  void reverse(fpreal gstart=0, fpreal gend=0, bool whole_chan = true);
451  // scroll on the y axis (returns success)
452  bool increaseKeyValues( fpreal delta );
453 
454  // DISABLING
455  bool isAllDisabled() const;
456  bool isAllEnabled() const;
457  bool isDisabled(fpreal gtime) const;
458  void disableAll(fpreal gtime);
459  void enableAll();
460  void disable(fpreal gstart, fpreal gend);
461  void enable(fpreal gstart, fpreal gend);
462 
463  // PENDING METHODS
464  int isPending() const
465  { return (myFlags & CH_CHANNEL_PENDING) ? 1 : 0; }
466  int isPending(fpreal gtime) const;
467  int isPendingLocal(fpreal ltime) const;
468  void clearPending();
469  void updatePending( fpreal gtime );
471  { return globalTime(myPendingEvalTime); }
472  int isPendingHold() const
473  { return (myFlags & CH_CHANNEL_PENDINGHOLD) ? 1 : 0; }
474  void setPendingHold( int state );
475 
476  // SAVE and LOAD
477  void save(std::ostream &os, int binary, bool compiled) const;
478  template <typename FPREAL_TYPE>
479  bool load(UT_IStream &is);
480  void display() const;
481  void displayAsKeys() const;
482 
483  void setDefaultValue(fpreal dv) { myDefValue = dv; }
484  fpreal getDefaultValue() const { return myDefValue; }
485 
486  void setDefaultString(const UT_String &dv)
487  { myDefString.harden(dv); }
488  UT_String getDefaultString() const { return myDefString; }
489 
490  void setChannelLeftType(CH_ChannelBehavior t);
491  void setChannelRightType(CH_ChannelBehavior t);
492  CH_ChannelBehavior getChannelLeftType(void) const { return myLeftType; }
493  CH_ChannelBehavior getChannelRightType(void) 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 { return myScope; }
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  }
603  inline CH_Segment *getEvaluationSegment(int thread)
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 preserveExtrema,
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 preserveExtrema );
656  void refit( fpreal tolerance, bool preserveExtrema,
657  fpreal from_gtime, fpreal to_gtime,
658  bool delete_old_segments);
659 
660  // SEGMENT MANAGEMENT
661  bool isEmpty() const;
662  int getNSegments() const;
663  int getNKeys() const;
664  int getNKeysBefore( fpreal gtime ) const;
665  int getNKeysBeforeOrAt( fpreal gtime ) const;
666 
667  fpreal getKeyTime( unsigned idx ) const;
668 
669  unsigned getSegmentIdx(fpreal local_time) const;
670  CH_Segment *getSegment(unsigned idx) const;
671  CH_Segment *getSegment(fpreal local_time) const;
672 
673  CH_Segment *getNextSegment(unsigned idx) const; // Depends on behavior
674  CH_Segment *getPrevSegment(unsigned idx) const; // Depends on behavior
675 
677  {
678  // empty means no keys in the channel if user delete them
679  // all
680  UT_ASSERT_P( isEmpty() || myEndSegment );
681  return isEmpty()
682  ? 0 : getSegment( (unsigned)0 );
683  }
685  {
686  // empty means no keys in the channel if user delete them
687  // all
688  UT_ASSERT_P( isEmpty() || myEndSegment );
689 
690  // old behaviour maintained (ie. don't use end segment)
691  return isEmpty()
692  ? 0 : getSegment( (unsigned)mySegments.entries()-1 );
693  }
694 
695  int64 getMemoryUsage(bool inclusive) const;
696 
697  // The first method takes global time, the second, segment local time.
698  void changeSegLength (CH_Segment *seg, fpreal gtime,
700  bool adjust_and_update = true);
701 
702  bool getHaveCompiledExpressions() const;
703 
704  bool verify();
705  bool verify(bool verify_tied_values);
706 
707  // Snapshots or buffer curves.
708  // Create a deep copy of the channel data for fast modifications and revert workflow.
709  // It's more intuitive than to have to do multiple undo to get back to the previous
710  // keyframes.
711  void saveSnapshot();
712  void undoSnapshot(CH_Channel *previous, bool previousSnapshotCleared);
713  bool loadSnapshot();
714  bool swapSnapshot();
715  bool clearSnapshot();
716  CH_Channel* getSnapshotChannel();
717 
718 
719  void smoothAutoSlopes( CH_Segment *seg=NULL );
720 
721 
722  // Layer Scope Flag
723  void setLayerScope(bool on_off);
724  bool isLayerScoped() const { return myLayerScope; }
725 
726  // Set an array pointer to capture the copyRange actions
727  void setCaptureCopiedKeys( UT_Array<fpreal> *capture_array );
728 
729  // chkey version of putFullKey() doesn't do the same validations as putFullKey()
730  void putChFullKey( fpreal gtime, CH_FullKey const& key, bool accel_ratios = true );
731 private:
732  CH_Channel( CH_Channel const& other ); // unimplemented
733 
734  void ensureEndSegmentCreated();
735  void updateEndSegment();
736  void destroyEndSegment();
737 
738  // TODO: Remove this. It's abysmally slow, doing a binary search each time
739  bool nextTimeInRange(UT_SuperIntervalR const& range,
740  fpreal &t, bool first) const;
741 
742  class BatchModifyScope;
743  friend class CH_Channel::BatchModifyScope;
744 
745  void moveKeyInternal(fpreal old_gtime, fpreal new_gtime,
746  BatchModifyScope &scope);
747  void splitSegment(fpreal gtime, bool accel_ratio = true);
748  void destroyKeyInternal(unsigned seg_i, BatchModifyScope &scope);
749 
750  // cuts out a portion of a channel. Returns an index at which the cut began
751  int cutOut( fpreal from_gtime, fpreal to_gtime );
752 
753  CH_Segment *appendSegment(CH_Segment *seg);
754 
755  // remove and delete the segment
756  void deleteSegment(unsigned idx);
757 
758  int getNDisableSegments(void) const
759  { return myDisableSegments.entries(); }
760  CH_Segment *getDisableSegment(unsigned idx) const
761  {
762  return (idx < myDisableSegments.entries()) ?
763  myDisableSegments(idx) : 0;
764  }
765 
766  CH_Segment *getDisableSegmentForLocalTime(fpreal local_time) const;
767  CH_Segment *getPrevDisableSegment(CH_Segment *) const;
768  CH_Segment *getNextDisableSegment(CH_Segment *) const;
769 
770  int getDisableSegmentIndex(fpreal ltime, bool closest_prev) const;
771 
772  CH_Segment *getFirstDisableSegment() const
773  {
774  return (myDisableSegments.entries() > 0) ?
775  myDisableSegments(0) : 0;
776  }
777  CH_Segment *getLastDisableSegment() const
778  {
779  return (myDisableSegments.entries() > 0)
780  ? myDisableSegments(myDisableSegments.entries()-1)
781  : 0;
782  }
783  CH_Segment *appendDisableSegment(CH_Segment *seg);
784 
785  CH_Segment *insertDisableSegment(CH_Segment *seg);
786  CH_Segment *insertDisableSegment(CH_Segment *seg, int idx);
787  CH_Segment *insertDisableSegment(CH_Segment *seg, CH_Segment *before);
788 
789  // Remove but don't delete
790  void removeDisableSegment(CH_Segment *seg);
791  void removeDisableSegment(int idx);
792 
793  void deleteDisableSegment(CH_Segment *);
794  void deleteDisableSegment(int idx);
795 
796  void setPending( bool on_off, fpreal ltime );
797  void updatePendingStateToManager();
798 
799  void deNormalize(fpreal scale);
800 
801  int isCooking() const
802  {
803  return (myFlags & CH_CHANNEL_COOKING) != 0;
804  }
805  void setCooking(bool on_off)
806  {
807  if (on_off) myFlags |= CH_CHANNEL_COOKING;
808  else myFlags &= ~CH_CHANNEL_COOKING;
809  }
810 
811  void adjustSegments(int begin_i, int end_i,
812  CH_CHANGE_TYPE event_type);
813 
814  // Get Segment methods that can return disabled segments.
815  CH_Segment *getFirstSegment(bool no_disabling ) const;
816  CH_Segment *getLastSegment(bool no_disabling ) const;
817  CH_Segment *getEndSegment(bool no_disabling ) const;
818  CH_Segment *getSegment(bool no_disabling, fpreal ltime ) const;
819 
820  enum chGetOrSampleReturn
821  {
822  Sampled, Get, FirstLast
823  };
824  chGetOrSampleReturn getOrSampleKey( fpreal ltime, CH_Key &key, bool accel_ratio, int thread );
825 
826  CH_Collection *myParent; // Who I belong to
827  UT_String myName;
828  UT_String myAlias;
829 
830  CH_ChannelBehavior myLeftType; // Type of channel
831  CH_ChannelBehavior myRightType; // Type of channel
832  CH_Segment *myEndSegment;
833 
834  fpreal myDefValue; // Default/Pending value
835  fpreal myStart; // Start time of channel
836  fpreal myLength; // Kept for efficiency (local)
837 
838  UT_String myDefString; // Default/Pending string value
839 
840  UT_ValArray<CH_Segment *> mySegments; // Array of segments
841  UT_ValArray<CH_Segment *> myDisableSegments;
842 
843  bool myScope;
844  bool myIsTemporary;
845  unsigned char myFlags;
846 
847 
848  fpreal myPendingEvalTime;
849 
850  bool mySnapshotCleared;
851  CH_Channel *mySnapshot;
852 
853  bool myLayerScope;
854 
855  UT_Array<fpreal> *myCaptureCopiedKeys;
856  bool myDoingChKey;
857 };
858 
860 
861 inline CH_Segment *
862 CH_Channel::getSegment(unsigned idx) const
863 {
864  if( idx<mySegments.entries() )
865  return mySegments(idx);
866  if( idx==(unsigned)-1 || idx==mySegments.entries() )
867  {
868  UT_ASSERT(myEndSegment || mySegments.entries() == 0);
869  return myEndSegment;
870  }
871  UT_ASSERT( false );
872  return NULL;
873 }
874 
875 inline int
877 {
878  return myEndSegment ? 1 + mySegments.entries() : 0;
879 }
880 
881 inline bool
883 {
884  return mySegments.isEmpty() && !myEndSegment;
885 }
886 
887 inline int
889 {
890  return getNSegments();
891 }
892 
893 inline fpreal
894 CH_Channel::getKeyTime( unsigned idx ) const
895 {
896  CH_Segment *segp;
897  if( idx == mySegments.entries() )
898  {
899  segp = myEndSegment;
900  UT_ASSERT( segp );
901  return globalTime( segp->getStart() );
902  }
903  segp = getSegment( idx );
904  UT_ASSERT( segp );
905  return globalTime( segp->getStart() );
906 }
907 
908 inline bool
910 {
911  return getNSegments() == 1;
912 }
913 
914 inline bool
916 {
917  // NB: This is actually slightly weaker than PRM_Float::isRotationParm()
918  return myName == "rx" || myName == "ry" || myName == "rz";
919 }
920 
921 
922 /// Const iterator over an interval
924 {
925 public:
927  : myChannel(NULL)
928  , myI(-1)
929  , myTol(0.0)
930  {
931  }
932 
934  {
935  ++myI;
936  return *this;
937  }
939  {
940  --myI;
941  return *this;
942  }
943 
944  bool atEnd() const
945  {
946  if (myI >= myChannel->getNSegments())
947  return true;
948  fpreal lt = localTime();
949  return !(myRange.myMaxInclusive ?
950  SYSisLessOrEqual(lt, myRange.max, myTol)
951  : SYSisLess(lt, myRange.max, myTol));
952  }
953  bool atPre() const
954  {
955  if (myI < 0)
956  return true;
957  fpreal lt = localTime();
958  return !(myRange.myMinInclusive ?
959  SYSisGreaterOrEqual(lt, myRange.min, myTol)
960  : SYSisGreater(lt, myRange.min, myTol));
961  }
962 
963  unsigned index() const
964  {
965  return (unsigned)myI;
966  }
967 
968  const CH_Segment &segment() const
969  {
970  return *(myChannel->getSegment((unsigned)myI));
971  }
972 
973  // Local time at start of segment
975  {
976  return myChannel->getSegment((unsigned)myI)->getStart();
977  }
978 
979  fpreal operator*() const { return myChannel->globalTime(localTime()); }
980 
981 protected:
983  const CH_Channel &ch, const UT_SuperIntervalR &range,
984  const bool ascending)
985  : myChannel(&ch)
986  , myRange(range)
987  , myTol(ch.getTolerance())
988  {
989  myRange.min = ch.localTime(myRange.min);
990  myRange.max = ch.localTime(myRange.max);
991  UT_ASSERT(myRange.min <= myRange.max);
992  if (ascending)
993  {
994  // If myRange.min is less than the first segment's start time, then
995  // the first segment is returned by getSegmentIdx().
996  myI = ch.getSegmentIdx(myRange.min);
997  CH_Segment *seg = ch.getSegment((unsigned)myI);
998  if (seg)
999  {
1000  fpreal lt = seg->getStart();
1001  if (range.myMinInclusive)
1002  {
1003  if (SYSisLess(lt, myRange.min, myTol))
1004  ++myI;
1005  }
1006  else
1007  {
1008  if (SYSisLessOrEqual(lt, myRange.min, myTol))
1009  ++myI;
1010  }
1011  }
1012  else
1013  {
1014  myI = ch.getNSegments();
1015  }
1016  UT_ASSERT(atEnd() || myRange.contains(localTime(), myTol));
1017  }
1018  else // descending
1019  {
1020  myI = ch.getSegmentIdx(myRange.max);
1021  CH_Segment *seg = ch.getSegment((unsigned)myI);
1022  if (seg)
1023  {
1024  fpreal lt = seg->getStart();
1025  if (range.myMaxInclusive)
1026  {
1027  if (SYSisGreater(lt, myRange.max, myTol))
1028  --myI;
1029  }
1030  else
1031  {
1032  if (SYSisGreaterOrEqual(lt, myRange.max, myTol))
1033  --myI;
1034  }
1035  }
1036  else
1037  {
1038  myI = -1;
1039  }
1040  UT_ASSERT(atPre() || myRange.contains(localTime(), myTol));
1041  }
1042  }
1043 
1044 private:
1045  const CH_Channel * myChannel;
1046  UT_SuperIntervalR myRange;
1047  int myI;
1048  fpreal myTol;
1049 
1050  friend class CH_Channel;
1051 };
1052 
1053 /// Iterator over an interval
1055 {
1056 public:
1058  : ConstIntervalIter()
1059  {
1060  }
1061 
1063  {
1064  return const_cast<CH_Segment &>(ConstIntervalIter::segment());
1065  }
1066 
1068  {
1070  return *this;
1071  }
1073  {
1075  return *this;
1076  }
1077 
1078 protected:
1080  const CH_Channel &ch, const UT_SuperIntervalR &range, bool reverse)
1081  : ConstIntervalIter(ch, range, reverse)
1082  {
1083  }
1084 
1085 private:
1086 
1087  friend class CH_Channel;
1088 };
1089 
1092  const UT_SuperIntervalR & range, const bool ascending) const
1093 {
1094  return IntervalIter(*this, range, ascending);
1095 }
1098  const UT_SuperIntervalR & range, const bool ascending) const
1099 {
1100  return ConstIntervalIter(*this, range, ascending);
1101 }
1102 
1103 /// This function stretches the modifies the given slope and accel values
1104 /// according to the given factors. If the accel value is given as a ratio,
1105 /// then accel_ratio should be true.
1106 CH_API extern void
1107 CHstretchSlopeAccel(fpreal xscale, fpreal yscale, fpreal &slope, fpreal &accel,
1108  bool accel_ratio);
1109 
1110 // this will move attempted_dt towards accepted_dt so that:
1111 // keys[i]+attempted_dt does not land on another key
1112 // attempted_dt stays on the same side of accepted_dt as it started
1113 // (so that if you're moving one way, they don't snap backwards before
1114 // where they started)
1115 // if snap_to_frame, attempted_dt+base_time will land on a frame
1116 CH_API extern void
1117 CHfindMoveKeysDelta( const CH_Channel *chp, bool snap_to_frame, fpreal base_time,
1118  const UT_FprealArray &orig_keys,
1119  fpreal accepted_dt, fpreal &attempted_dt );
1120 
1121 CH_API extern void
1122 CHmoveKeysWithDelta( CH_Channel *chp, const UT_FprealArray &orig_keys,
1123  fpreal old_accepted_dt, fpreal new_accepted_dt );
1124 
1125 ///////////////////////////////////////////////////////////////////////////////
1126 //
1127 // Inline Implementations
1128 //
1129 
1130 /*static*/ inline fpreal
1132 {
1133  const CH_EvalContext & ctx = CHgetManager()->evalContext(thread);
1134  const CH_Channel * eval_channel = ctx.channel();
1135  const CH_Segment * segp = ctx.segment();
1136 
1137  if (segp)
1138  {
1139  if (eval_channel->isPending(ctx.time()))
1140  return eval_channel->getDefaultValue();
1141  else
1142  return segp->getInValue();
1143  }
1144 
1145  return 0.0f;
1146 }
1147 
1148 /*static*/ inline void
1150  fpreal &v0, fpreal &v1, int thread)
1151 {
1152  CH_Manager & mgr = *CHgetManager();
1153  CH_EvalContext & ctx = mgr.evalContext(thread);
1154  const CH_Channel * eval_channel = ctx.channel();
1155  const CH_Segment * segp = ctx.segment();
1156 
1157  if (eval_channel)
1158  {
1159  t = eval_channel->localTime(ctx.time());
1160  if (segp)
1161  {
1162  t0 = segp->getStart();
1163  t1 = segp->getEnd();
1164  if( eval_channel->isPendingLocal(t) )
1165  {
1166  v0 = v1 = eval_channel->getDefaultValue();
1167  t0 = t1 = t;
1168  }
1169  else
1170  {
1171  v0 = segp->getInValue();
1172  v1 = segp->getOutValue();
1173  if( segp->isEndSegment() )
1174  {
1175  // Since our segment length is zero, we want fake it so
1176  // that it uses either the in or out values because most
1177  // existing expression functions will take the average of
1178  // them when encountering a zero length segement.
1179  // NB: the in/out values are swapped on end segments.
1180  if (SYSisGreaterOrEqual(t, t0, mgr.getTolerance()))
1181  v1 = v0;
1182  else
1183  v0 = v1;
1184  }
1185  }
1186  }
1187  else
1188  {
1189  t0 = eval_channel->getStart();
1190  t1 = eval_channel->getEnd();
1191  v0 = v1 = 0;
1192  }
1193  }
1194  else
1195  {
1196  t = 0.0f;
1197  t0 = 0.0f;
1198  t1 = 0.0f;
1199  v0 = 0.0f;
1200  v1 = 0.0f;
1201  }
1202 }
1203 
1204 /*static*/ inline void
1206  int thread)
1207 {
1208  CH_EvalContext & ctx = CHgetManager()->evalContext(thread);
1209  const CH_Segment * segp = ctx.segment();
1210 
1211  if (segp)
1212  {
1213  if (m0) *m0 = segp->getInSlope();
1214  if (m1) *m1 = segp->getOutSlope();
1215  if (a0) *a0 = segp->getInAccel();
1216  if (a1) *a1 = segp->getOutAccel();
1217  }
1218  else
1219  {
1220  if (m0) *m0 = 0.0f;
1221  if (m1) *m1 = 0.0f;
1222  if (a0) *a0 = 0.0f;
1223  if (a1) *a1 = 0.0f;
1224  }
1225 }
1226 
1227 #endif // __CH_Channel_h__
Iterator over an interval.
Definition: CH_Channel.h:1054
GLint first
Definition: glcorearb.h:404
CH_ExprLanguage myRevExprLanguage
Definition: CH_Channel.h:164
fpreal localTime(fpreal t) const
Definition: CH_Channel.h:533
unsigned getSegmentIdx(fpreal local_time) const
bool myUseExpression
Definition: CH_Channel.h:143
GLenum GLint * range
Definition: glcorearb.h:1924
const UT_String & getName(void) const
Definition: CH_Channel.h:233
bool myUseRevExpression
Definition: CH_Channel.h:162
CH_ChannelBehavior getChannelLeftType(void) const
Definition: CH_Channel.h:492
CH_API void CHfindMoveKeysDelta(const CH_Channel *chp, bool snap_to_frame, fpreal base_time, const UT_FprealArray &orig_keys, fpreal accepted_dt, fpreal &attempted_dt)
UT_String getDefaultString() const
Definition: CH_Channel.h:488
static void getGlueTime(fpreal &t, fpreal &t0, fpreal &t1, fpreal &v0, fpreal &v1, int thread)
Definition: CH_Channel.h:1149
CH_Segment * getEvaluationSegment(int thread)
Definition: CH_Channel.h:603
bool isEndSegment() const
Definition: CH_Segment.h:274
CH_ExprLanguage
IntervalIter intervalIter(const UT_SuperIntervalR &range, const bool ascending=true) const
Definition: CH_Channel.h:1091
GLint left
Definition: glcorearb.h:2004
CH_Key()
Definition: CH_Channel.h:101
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
Definition: UT_ArraySet.h:1561
Const iterator over an interval.
Definition: CH_Channel.h:923
CH_StringMeaning
const GLdouble * v
Definition: glcorearb.h:836
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
CH_ChannelFlag
Definition: CH_Channel.h:53
fpreal globalTime(fpreal t) const
Definition: CH_Channel.h:536
const GLuint GLenum const void * binary
Definition: glcorearb.h:1923
bool isRotationChannel() const
Definition: CH_Channel.h:915
GLsizei const GLchar *const * path
Definition: glcorearb.h:3340
bool myEvaluatedSlopes
Definition: CH_Channel.h:98
const CH_Segment * segment() const
Definition: CH_Manager.h:92
bool isTemporary() const
Definition: CH_Channel.h:502
bool isEmpty() const
Definition: CH_Channel.h:882
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
fpreal getEnd() const
Definition: CH_Channel.h:540
void setIsTemporary(bool temp)
Definition: CH_Channel.h:501
GLint GLuint mask
Definition: glcorearb.h:123
void setName(const char *s)
Definition: CH_Channel.h:238
CH_FullKey & operator=(CH_FullKey const &other)
CH_GetKeyExtend
Definition: CH_Channel.h:73
const CH_Segment & segment() const
Definition: CH_Channel.h:968
CH_Segment & segment() const
Definition: CH_Channel.h:1062
2D Vector class.
Definition: UT_Vector2.h:137
unsigned index() const
Definition: CH_Channel.h:963
bool isLayerScoped() const
Definition: CH_Channel.h:724
const CH_EvalContext & evalContext(int thread) const
Definition: CH_Manager.h:1176
bool isChangeActive() const
Definition: CH_Channel.h:510
class CH_API IntervalIter
Definition: CH_Channel.h:283
bool hasOnlyOneSegment() const
Definition: CH_Channel.h:909
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
int canAccess(uint mask) const
Definition: CH_Channel.h:524
static fpreal getGlueIV(int thread)
Definition: CH_Channel.h:1131
fpreal getOutValue(void) const
Definition: CH_Segment.h:279
IntervalIter & operator--()
Definition: CH_Channel.h:1072
long long int64
Definition: SYS_Types.h:106
fpreal getDefaultValue() const
Definition: CH_Channel.h:484
GA_API const UT_StringHolder scale
class CH_API ConstIntervalIter
Definition: CH_Channel.h:282
ConstIntervalIter constIntervalIter(const UT_SuperIntervalR &range, const bool ascending=true) const
Definition: CH_Channel.h:1097
GLdouble n
Definition: glcorearb.h:2007
ConstIntervalIter & operator--()
Definition: CH_Channel.h:938
GLfloat f
Definition: glcorearb.h:1925
fpreal getEnd(void) const
Definition: CH_Segment.h:316
UT_String myRevExpression
Definition: CH_Channel.h:163
CH_ChannelBehavior
Definition: CH_Channel.h:39
CH_CHANGE_TYPE
CH_Manager * CHgetManager()
Definition: CH_Manager.h:1594
ConstIntervalIter & operator++()
Definition: CH_Channel.h:933
void setCollection(CH_Collection *chp)
Definition: CH_Channel.h:497
const CH_Segment * getEvaluationSegment(int thread) const
Definition: CH_Channel.h:599
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
CH_ChannelBehavior getChannelRightType(void) const
Definition: CH_Channel.h:493
fpreal getLength() const
Definition: CH_Channel.h:541
bool getLocked() const
Definition: CH_Channel.h:514
UT_String myExpression
Definition: CH_Channel.h:144
void display() const
fpreal getKeyTime(unsigned idx) const
Definition: CH_Channel.h:894
fpreal myTimeValue
Definition: CH_Channel.h:97
int isPending() const
Definition: CH_Channel.h:464
void setDefaultValue(fpreal dv)
Definition: CH_Channel.h:483
bool isScoped() const
Definition: CH_Channel.h:564
IntervalIter(const CH_Channel &ch, const UT_SuperIntervalR &range, bool reverse)
Definition: CH_Channel.h:1079
CH_Segment * getLastSegment() const
Definition: CH_Channel.h:684
int isPendingLocal(fpreal ltime) const
GLboolean * data
Definition: glcorearb.h:130
GLuint const GLchar * name
Definition: glcorearb.h:785
CH_Segment * getSegment(unsigned idx) const
Definition: CH_Channel.h:862
fpreal getStart(void) const
Definition: CH_Segment.h:315
unsigned int uint
Definition: SYS_Types.h:39
void reverse(fpreal gstart=0, fpreal gend=0, bool whole_chan=true)
GLfloat v0
Definition: glcorearb.h:815
IntervalIter & operator++()
Definition: CH_Channel.h:1067
void setChangeActive(int state)
Definition: CH_Channel.h:505
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:446
fpreal getInValue(void) const
Definition: CH_Segment.h:278
CH_Collection * getCollection()
Definition: CH_Channel.h:499
CH_ExprLanguage myExprLanguage
Definition: CH_Channel.h:145
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:269
fpreal getStart() const
Definition: CH_Channel.h:539
fpreal getInSlope(void) const
Definition: CH_Segment.h:280
CH_API void CHmoveKeysWithDelta(CH_Channel *chp, const UT_FprealArray &orig_keys, fpreal old_accepted_dt, fpreal new_accepted_dt)
void stretch(fpreal xscale, fpreal yscale, bool accel_ratio)
CH_ValueTypes
Definition: CH_Types.h:70
int getNSegments() const
Definition: CH_Channel.h:876
void reverse()
CH_Segment * getFirstSegment() const
Definition: CH_Channel.h:676
fpreal getOutSlope(void) const
Definition: CH_Segment.h:281
CH_Manager * getManager() const
Definition: CH_Channel.h:241
#define CH_API
Definition: CH_API.h:10
CH_API void CHstretchSlopeAccel(fpreal xscale, fpreal yscale, fpreal &slope, fpreal &accel, bool accel_ratio)
int isPendingHold() const
Definition: CH_Channel.h:472
void display() const
const CH_Collection * getCollection() const
Definition: CH_Channel.h:498
GLfloat GLfloat v1
Definition: glcorearb.h:816
GLuint GLfloat * val
Definition: glcorearb.h:1607
void setAlias(const char *s)
Definition: CH_Channel.h:239
int getChanged() const
Definition: CH_Channel.h:518
fpreal getPendingEvalTime() const
Definition: CH_Channel.h:470
CH_SegmentScale
Definition: CH_Types.h:64
#define UT_SWAPPER_CLASS(T)
Definition: UT_Swap.h:60
fpreal getTolerance() const
Definition: CH_Channel.h:243
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
int getNKeys() const
Definition: CH_Channel.h:888
CH_API char CHvalueNames[2][CH_NUM_VALUES]
static void getGlueSlope(fpreal *m0, fpreal *m1, fpreal *a0, fpreal *a1, int thread)
Definition: CH_Channel.h:1205
ConstIntervalIter(const CH_Channel &ch, const UT_SuperIntervalR &range, const bool ascending)
Definition: CH_Channel.h:982
fpreal getInAccel(void) const
Definition: CH_Segment.h:282
void setDefaultString(const UT_String &dv)
Definition: CH_Channel.h:486
bool contains(T arg, T tol=T(SYS_FTOLERANCE)) const
fpreal getTolerance() const
Definition: CH_Manager.h:981
fpreal time() const
Definition: CH_Manager.h:82
fpreal getOutAccel(void) const
Definition: CH_Segment.h:283
const CH_Channel * channel() const
Definition: CH_Manager.h:88
bool isEmpty() const
Returns true iff there are no occupied elements in the array.
Definition: UT_Array.h:448
GLenum src
Definition: glcorearb.h:1792