HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CH_Segment.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: This is the class definition for a segment.
9  *
10 */
11 
12 #ifndef __CH_Segment_h__
13 #define __CH_Segment_h__
14 
15 #include "CH_API.h"
16 #include "CH_ExprLanguage.h"
17 #include "CH_Manager.h"
18 #include "CH_Types.h"
19 
20 #include <UT/UT_Vector3.h>
21 #include <SYS/SYS_Types.h>
22 
23 #include <deque>
24 #include <iosfwd>
25 
26 
27 #define CH_EXPRESSION_CONSTANT "constant()"
28 #define CH_EXPRESSION_BEZIER "bezier()"
29 #define CH_EXPRESSION_LINEAR "linear()"
30 #define CH_EXPRESSION_CUBIC "cubic()"
31 #define CH_EXPRESSION_EASE "ease()"
32 #define CH_EXPRESSION_EASEIN "easein()"
33 #define CH_EXPRESSION_EASEOUT "easeout()"
34 #define CH_EXPRESSION_SPLINE "spline()"
35 #define CH_EXPRESSION_QLINEAR "qlinear()"
36 #define CH_EXPRESSION_QCUBIC "qcubic()"
37 
38 #define CH_SEGMENT_MINIMUM_LENGTH 0.000001F
39 
40 class CH_Channel;
41 class CH_Expression;
42 class CH_Manager;
43 class CH_Segment;
44 class CH_TimeGroup;
45 
46 class UT_String;
47 
48 enum
49 {
50  CH_STRETCH_IN = 0x01,
52 };
53 
55 {
56 public:
58  {
59  setDefaults();
60  }
61  void save(std::ostream &os, int binary) const;
62  bool load(UT_IStream &is);
63 
64  void setDefaults();
65  unsigned isDefault() const;
66 
67  unsigned isConstant:1,
68  isBezier:1,
69  isLinear:1,
70  isCubic:1,
71  isEase:1,
72  isEaseIn:1,
73  isEaseOut:1,
74  isLocked:1,
75  isSpline:1,
76  modified:1,
77  tieOutAccel:1,
78  tieInAccel:1,
79  tieOutSlope:1,
80  tieInSlope:1,
81  tieOutValue:1,
82  tieInValue:1,
83  lockEnd:1,
84  lockStart:1,
85  lockLength:1,
86  isCooking:1,
87  isQLinear:1,
88  isQCubic:1,
89  autoInSlope:1,
90  autoOutSlope:1,
91  modifyingAccel:1,
92  isChop:1;
93 };
94 
96 {
97 public:
98  fpreal t0, t1;
99  fpreal iv, ov, im, om, isl, osl;
100 
102 
103  CH_SegmentValues( CH_Segment const& seg );
104 
105  void display();
106 };
107 
108 #define CH_MAX_SLOPE 1e8
109 #define CH_MAX_ACCEL 1e8
110 
112 {
113 public:
114  // Default constructor creates an expression with which returns the
115  // default value
116  CH_Segment(fpreal defVal, CH_Channel *mom, fpreal len = 0);
117 
118  // Copy constructor.
119  CH_Segment(const CH_Segment &from);
120 
121  // Constructor for an expression segment. By default, there is
122  // no callback function and no raw array
123  CH_Segment(const char *expr, CH_ExprLanguage language, CH_Channel *mom,
124  fpreal len = 0);
125 
126  ~CH_Segment();
127 
128  int64 getMemoryUsage(bool inclusive) const;
129 
130  CH_Manager *getManager() const;
131  fpreal getTolerance() const;
132 
133  void save(std::ostream &os, int binary, bool compiled,
134  bool disabled) const;
135  template <typename FPREAL_TYPE>
136  bool load(UT_IStream &is, bool disabled,
137  bool reload=false);
138 
139  // Now we define some operators so that we can use these objects
140  // in the UT_Array of channels
141  CH_Segment &operator= (const CH_Segment &from);
142  int operator==(const CH_Segment &) { return 0; }
143 
144  // The segment may be evaluated by using any of the following
145  // evaluation methods. The segment can be evaluated by relative
146  // time, absolute time or both.
147  // If extend is non-zero, the left(1) or right(2) value along the
148  // slope is calculated accordingly.
149  fpreal evaluate(fpreal ltime, bool extend /*=false*/,
150  int thread);
151  void evaluateString(UT_String &result,
152  fpreal ltime, bool extend /*=false*/,
153  int thread);
154 
155  // Clears and reparses the expression:
156  void unresolveLocalVars(int thread);
157 
158  CH_Channel *getChannel(void) const { return myParent; }
159  void setChannel(CH_Channel *chp) { myParent = chp; }
160 
161  void setExprLanguage(CH_ExprLanguage language);
162  CH_ExprLanguage getExprLanguage() const;
163 
164  // If we were to ask for the value of the segment as a string, this
165  // function returns what the meaning of that string would be (either a
166  // literal or expression in some language).
167  CH_StringMeaning getStringMeaning();
168 
169  int isMatchFunction(void) const;
170  int isLockedSegment() const { return myFlags.isLocked; }
171  int isChopSegment() const { return myFlags.isChop; }
172 
173  CH_SegmentFlags getFlags() const { return myFlags; }
174  void lockLength(int onoff) { myFlags.lockLength = onoff; }
175  void lockStart(int onoff) { myFlags.lockStart = onoff; }
176  void lockEnd(int onoff) { myFlags.lockEnd = onoff; }
177  void tieInValue(int onoff, bool dotie = true);
178  void tieOutValue(int onoff, bool dotie = true);
179  void tieInSlope(int onoff, bool dotie = true,
180  fpreal ar = 0.0 );
181  void tieOutSlope(int onoff, bool dotie = true,
182  fpreal ar = 0.0 );
183  void tieInAccel(int onoff, bool dotie = true);
184  void tieOutAccel(int onoff, bool dotie = true);
185 
186  void autoInSlope(int onoff);
187  void autoOutSlope(int onoff);
188 
189  // Turn cooking on and set the sample array size or turn cooking off...
190  void cook(int state, int unused = 0);
191 
192  int isCooking() const { return myFlags.isCooking; }
193  int isLengthLocked() const { return myFlags.lockLength; }
194  int isStartLocked() const { return myFlags.lockStart; }
195  int isEndLocked() const { return myFlags.lockEnd; }
196  int isInValueTied() const { return myFlags.tieInValue; }
197  int isOutValueTied() const { return myFlags.tieOutValue; }
198  int isInSlopeTied() const { return myFlags.tieInSlope; }
199  int isOutSlopeTied() const { return myFlags.tieOutSlope; }
200  int isInAccelTied() const { return myFlags.tieInAccel; }
201  int isOutAccelTied() const { return myFlags.tieOutAccel; }
202  int isConstant() const { return myFlags.isConstant; }
203  int isCubic() const { return myFlags.isCubic; }
204  int isBezier() const { return myFlags.isBezier; }
205  int isLinear() const { return myFlags.isLinear; }
206  int isQLinear() const { return myFlags.isQLinear; }
207  int isQCubic() const { return myFlags.isQCubic; }
208  int isQuaternion() const
209  { return isQLinear() || isQCubic(); }
210 
211  int isInSlopeAuto() const { return myFlags.autoInSlope; }
212  int isOutSlopeAuto() const { return myFlags.autoOutSlope; }
213 
214  int isInValueUsed(); // These methods query the
215  int isOutValueUsed(); // expression to find out
216  int isInSlopeUsed();
217  int isOutSlopeUsed();
218  int isInAccelUsed();
219  int isOutAccelUsed();
220  int isSplineUsed();
221 
222  // For simple functions that CH_SegmentFlags supports, return the
223  // CH_Support.h user flags for whether the value/slope/accels are used
224  // without needing to evaluate the expression. Returns false if all of the
225  // CH_SegmentFlags::isCubic, isBezier, etc. are false.
226  bool getFunctionKeyUserFlags(int thread, unsigned &flags);
227 
228  // Does a quick check to see if this segment is time dependent, using the
229  // flags set from the last evaluation.
230  bool isTimeDependent() const;
231  // If evaluate_to_find_out is false, the expression's flags will just be
232  // checked. In that case, if the expression was never evaluated since
233  // it last changed, this function may return that it's not time dependent
234  // even if it is.
235  bool isTimeDependent(bool evaluate_to_find_out,
236  int thread) const;
237 
238  // This function will return if the value is time dependent, and, if
239  // it's not, the value argument will be set. This way, you can compare
240  // adjacent values between segments to quickly check for time dependencies.
241  // This function will evaluate the expression if it's not already flagged
242  // as time dependent.
243  bool isTimeDependentAndGetFloat(fpreal &value,
244  int thread) const;
245 
246  // This function is like isTimeDependentAndGetFloat(), except it will
247  // evaluate the expression as a string. Note that the char* may be
248  // set to null if the segment is time dependent. If it's not null, it
249  // points to a strdup'd string that you must free().
250  bool isTimeDependentAndGetString(UT_String &value,
251  int thread) const;
252 
253  bool hasNonIntegerKeys() const;
254  unsigned isDataDependent() const;
255 
256  // The following methods are used to change the segment times
257  // (start, end, duration), and also for checking whether the
258  // segment can be changed.
259  int canChange(fpreal start, fpreal end) const;
260  void changeLength(fpreal len,
262  bool accel_ratio = true);
263  void changeTimes(fpreal s, fpreal e);
264 
265  // This method should only be called by CH_Channel - hands off.
266  void stretch(fpreal scale, int adjust_slopes,
267  int adjust_accel);
268 
269  // Some query methods
270  const char *getExpression(void) const;
271  const CH_Expression *getCHExpr() const { return myExpression; }
272  CH_Expression *getCHExpr() { return myExpression; }
273 
274  bool isEndSegment() const
275  {
276  return myLength == CONST_FPREAL(0);
277  }
278  fpreal getInValue(void) const { return inValue; }
279  fpreal getOutValue(void) const { return outValue; }
280  fpreal getInSlope(void) const { return inSlope; }
281  fpreal getOutSlope(void) const { return outSlope; }
282  fpreal getInAccel(void) const { return inAccel; }
283  fpreal getOutAccel(void) const { return outAccel; }
285  {
286  return getAccelRatio( inSlope, inAccel, myLength );
287  }
289  {
290  return getAccelRatio( outSlope, outAccel,
291  myLength );
292  }
293  static fpreal getAccelRatio(fpreal slope, fpreal accel,
294  fpreal length);
295  static fpreal getAccelFromRatio(fpreal slope, fpreal ratio,
296  fpreal length)
297  {
298  if( length==0.0 )
299  length = 1.0;
300  return length * ratio * SYSsqrt( slope*slope + 1 );
301  }
302 
303  CH_Segment *getNext() { return myNext; }
304  const CH_Segment *getNext() const { return myNext; }
305  void setNext(CH_Segment *segp)
306  { myNext = segp; }
307  CH_Segment *getPrev() { return myPrev; }
308  const CH_Segment *getPrev() const { return myPrev; }
309  void setPrev(CH_Segment *segp)
310  { myPrev = segp; }
311 
312  fpreal getLength (void) const { return myLength; }
313  fpreal getILength(void) const { return myInverseLength; }
314 
315  fpreal getStart(void) const { return myStart; }
316  fpreal getEnd (void) const { return myEnd; }
317 
319  {
320  return (t - myStart) * myInverseLength;
321  }
322 
323  void changeExpression(const char *expr,
324  CH_ExprLanguage language, bool convert_accels);
325  void changeExpression(const char *expr,
326  CH_ExprLanguage language);
327 
328  // Return whether or not an expression is a call to an animation function.
329  // Note that such expressions are compatible between different languages.
330  // The static method is for an arbitrary expression string and the
331  // non-static is for this segment.
332  static bool expressionIsAnimationFunctionCall(
333  const char *expression);
334  bool expressionIsAnimationFunctionCall();
335 
336  // When an application calls the following methods to set in/out values,
337  // they should leave the doTie as 1, it's only used internally.
338  void setInValue(fpreal v, bool dotie = true);
339  void setOutValue(fpreal v, bool dotie = true);
340  void setInSlope(fpreal v, bool dotie = true, fpreal ar = 0.0);
341  void setOutSlope(fpreal v, bool dotie = true, fpreal ar = 0.0);
342  void setInAccel(fpreal v, bool dotie = true);
343  void setOutAccel(fpreal v, bool dotie = true);
344  void setInAccelRatio(fpreal ratio, bool dotie = true)
345  {
346  fpreal v = getAccelFromRatio(inSlope, ratio,
347  myLength);
348  setInAccel( v, dotie );
349  }
350  void setOutAccelRatio(fpreal ratio, bool dotie = true )
351  {
352  fpreal v = getAccelFromRatio(outSlope, ratio,
353  myLength);
354  setOutAccel( v, dotie );
355  }
356  void clampInAccel();
357  void clampOutAccel();
358  void normalizeAccels();
359 
361  {
362  myPrev = p;
363  myNext = n;
364  }
365 
366  // Sorry, you can only flag a segment as being changed, it's got it's
367  // own internal mechanism for flagging this
368  void setChanged();
369 
370  // Only the CH_Channel class should call the following method(s)
371  void reverse();
372 
373  // Op dependencies
374  void buildOpDependencies(void *ref_id, int thread);
375  int changeOpRef(const char *new_fullpath,
376  const char *old_fullpath,
377  const char *old_cwd,
378  const char *chan_name,
379  const char *old_chan_name,
380  int thread);
381 
382  int findString(const char *str, bool fullword,
383  bool usewildcards) const;
384  int changeString(const char *from, const char *to,
385  bool fullword, int thread);
386 
387  void transferGroup(CH_Segment &from);
388 
389  int wasModified() const { return myFlags.modified; }
390  void setModified(int onOff);
391 
392  void dirtyExprCache();
393 
394  fpreal getValue(bool left, CH_ValueTypes t) const;
395  void setValue(bool left, CH_ValueTypes t, fpreal value);
396  bool getValueValid(bool left, CH_ValueTypes t);
397  bool getValueTied(bool left, CH_ValueTypes t) const;
398  void setValueTied(bool left, CH_ValueTypes t, bool on_off);
399  bool getValueAuto(bool left, CH_ValueTypes t) const;
400  void setValueAuto(bool left, CH_ValueTypes t, bool on_off);
401 
402  void display();
403 
404  CH_TimeGroup *getTimeGroup(void) const { return myTimeGroup; }
405 
406 private:
407  void setTimeGroup(CH_TimeGroup *g, bool refresh=true);
408 
409  void setExpression(const CH_Expression *newexpr);
410  void checkExpression();
411  void constructorInit(void); // Initialize all values
412  void isCooking(int state) // Toggle state during cook
413  { myFlags.isCooking = state; }
414  bool loadTimeGroups(UT_IStream &is);
415  void saveTimeGroups(std::ostream &is, int binary) const;
416 
417  void holdLastKey(fpreal v, bool dotie);
418 
419  void updateExprFlags();
420 
421  // the member variables marked with (*) should be removed as they are
422  // actually useless
423 
424  CH_SegmentFlags myFlags;
425 
426  // Here is the local context information for the segment. It is
427  // be used for evaluation of the segment.
428  //
429  // All times and lengths of time are in the channel local time.
430  CH_Expression *myExpression;
431 
432  fpreal inValue, outValue;
433  fpreal inSlope, outSlope;
434  fpreal inAccel, outAccel;
435 
436  CH_TimeGroup *myTimeGroup;
437 
438  // (*) we shouldn't store length, just use getNext()->myStart - myStart
439  // storing inverse length is acceptable
440  fpreal myLength;
441  fpreal myInverseLength; // Inverse stored for speed
442 
443  // (*) myEnd is redundant, and is not really that much more efficient
444  fpreal myStart, myEnd; // Redundant; for efficiency
445 
446  CH_Channel *myParent; // Our channel.
447 
448  // (**) ideally we would store segments in a ref array, in which case
449  // getNext could ideally be (this+1), ditto for prev, but there are some
450  // boundary cases of course where this gets weird
451  CH_Segment *myPrev, *myNext; // For easy reference
452 
453  friend class CH_TimeGroup;
454 };
455 
456 #endif
void setOutAccelRatio(fpreal ratio, bool dotie=true)
Definition: CH_Segment.h:350
void setPrev(CH_Segment *segp)
Definition: CH_Segment.h:309
fpreal getInAccelRatio() const
Definition: CH_Segment.h:284
fpreal relativeTime(fpreal t) const
Definition: CH_Segment.h:318
int isInValueTied() const
Definition: CH_Segment.h:196
bool isEndSegment() const
Definition: CH_Segment.h:274
CH_ExprLanguage
GLint left
Definition: glcorearb.h:2004
CH_StringMeaning
CH_Expression * getCHExpr()
Definition: CH_Segment.h:272
const GLdouble * v
Definition: glcorearb.h:836
int isQLinear() const
Definition: CH_Segment.h:206
GLuint start
Definition: glcorearb.h:474
const GLuint GLenum const void * binary
Definition: glcorearb.h:1923
GLboolean GLboolean g
Definition: glcorearb.h:1221
CH_Channel * getChannel(void) const
Definition: CH_Segment.h:158
GLbitfield flags
Definition: glcorearb.h:1595
int isLengthLocked() const
Definition: CH_Segment.h:193
static fpreal getAccelFromRatio(fpreal slope, fpreal ratio, fpreal length)
Definition: CH_Segment.h:295
int isCubic() const
Definition: CH_Segment.h:203
int isEndLocked() const
Definition: CH_Segment.h:195
int isQuaternion() const
Definition: CH_Segment.h:208
int isOutSlopeTied() const
Definition: CH_Segment.h:199
int isStartLocked() const
Definition: CH_Segment.h:194
fpreal getOutValue(void) const
Definition: CH_Segment.h:279
long long int64
Definition: SYS_Types.h:106
GA_API const UT_StringHolder scale
GLdouble n
Definition: glcorearb.h:2007
int isInAccelTied() const
Definition: CH_Segment.h:200
fpreal getEnd(void) const
Definition: CH_Segment.h:316
int isLockedSegment() const
Definition: CH_Segment.h:170
int isConstant() const
Definition: CH_Segment.h:202
int isOutAccelTied() const
Definition: CH_Segment.h:201
#define CONST_FPREAL(c)
Definition: SYS_Types.h:319
CH_TimeGroup * getTimeGroup(void) const
Definition: CH_Segment.h:404
GLuint GLuint end
Definition: glcorearb.h:474
int isCooking() const
Definition: CH_Segment.h:192
int isLinear() const
Definition: CH_Segment.h:205
int isOutValueTied() const
Definition: CH_Segment.h:197
CH_Segment * getPrev()
Definition: CH_Segment.h:307
void lockLength(int onoff)
Definition: CH_Segment.h:174
const CH_Expression * getCHExpr() const
Definition: CH_Segment.h:271
fpreal getStart(void) const
Definition: CH_Segment.h:315
const CH_Segment * getPrev() const
Definition: CH_Segment.h:308
int isInSlopeTied() const
Definition: CH_Segment.h:198
void lockStart(int onoff)
Definition: CH_Segment.h:175
void setNext(CH_Segment *segp)
Definition: CH_Segment.h:305
fpreal getInValue(void) const
Definition: CH_Segment.h:278
int isInSlopeAuto() const
Definition: CH_Segment.h:211
int isBezier() const
Definition: CH_Segment.h:204
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:269
fpreal getInSlope(void) const
Definition: CH_Segment.h:280
int operator==(const CH_Segment &)
Definition: CH_Segment.h:142
CH_ValueTypes
Definition: CH_Types.h:70
void setPrevNext(CH_Segment *p, CH_Segment *n)
Definition: CH_Segment.h:360
fpreal getOutSlope(void) const
Definition: CH_Segment.h:281
#define CH_API
Definition: CH_API.h:10
int isChopSegment() const
Definition: CH_Segment.h:171
int wasModified() const
Definition: CH_Segment.h:389
int isQCubic() const
Definition: CH_Segment.h:207
CH_SegmentScale
Definition: CH_Types.h:64
CH_Segment * getNext()
Definition: CH_Segment.h:303
void lockEnd(int onoff)
Definition: CH_Segment.h:176
fpreal getOutAccelRatio() const
Definition: CH_Segment.h:288
CH_SegmentFlags getFlags() const
Definition: CH_Segment.h:173
fpreal getILength(void) const
Definition: CH_Segment.h:313
const CH_Segment * getNext() const
Definition: CH_Segment.h:304
int isOutSlopeAuto() const
Definition: CH_Segment.h:212
fpreal getInAccel(void) const
Definition: CH_Segment.h:282
void setChannel(CH_Channel *chp)
Definition: CH_Segment.h:159
fpreal getOutAccel(void) const
Definition: CH_Segment.h:283
fpreal getLength(void) const
Definition: CH_Segment.h:312
void setInAccelRatio(fpreal ratio, bool dotie=true)
Definition: CH_Segment.h:344
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794