Blender  V3.3
fcurve_driver.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2009 Blender Foundation, Joshua Leung. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "DNA_anim_types.h"
11 #include "DNA_constraint_types.h"
12 #include "DNA_object_types.h"
13 
14 #include "BLI_alloca.h"
15 #include "BLI_expr_pylike_eval.h"
16 #include "BLI_listbase.h"
17 #include "BLI_math.h"
18 #include "BLI_string_utils.h"
19 #include "BLI_threads.h"
20 #include "BLI_utildefines.h"
21 
22 #include "BLT_translation.h"
23 
24 #include "BKE_action.h"
25 #include "BKE_animsys.h"
26 #include "BKE_armature.h"
27 #include "BKE_constraint.h"
28 #include "BKE_fcurve_driver.h"
29 #include "BKE_global.h"
30 #include "BKE_object.h"
31 
32 #include "RNA_access.h"
33 #include "RNA_path.h"
34 
35 #include "atomic_ops.h"
36 
37 #include "CLG_log.h"
38 
39 #ifdef WITH_PYTHON
40 # include "BPY_extern.h"
41 #endif
42 
43 #ifdef WITH_PYTHON
44 static ThreadMutex python_driver_lock = BLI_MUTEX_INITIALIZER;
45 #endif
46 
47 static CLG_LogRef LOG = {"bke.fcurve"};
48 
49 /* -------------------------------------------------------------------- */
53 /* TypeInfo for Driver Variables (dvti) */
54 typedef struct DriverVarTypeInfo {
55  /* Evaluation callback. */
56  float (*get_value)(ChannelDriver *driver, DriverVar *dvar);
57 
58  /* Allocation of target slots. */
59  int num_targets; /* Number of target slots required. */
60  const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots. */
61  short target_flags[MAX_DRIVER_TARGETS]; /* Flags defining the requirements for each slot. */
63 
64 /* Macro to begin definitions */
65 #define BEGIN_DVAR_TYPEDEF(type) {
66 
67 /* Macro to end definitions */
68 #define END_DVAR_TYPEDEF }
69 
72 /* -------------------------------------------------------------------- */
80 static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
81 {
82  PointerRNA id_ptr, ptr;
83  PropertyRNA *prop;
84  ID *id;
85  int index = -1;
86  float value = 0.0f;
87 
88  /* Sanity check. */
89  if (ELEM(NULL, driver, dtar)) {
90  return 0.0f;
91  }
92 
93  id = dtar->id;
94 
95  /* Error check for missing pointer. */
96  if (id == NULL) {
97  if (G.debug & G_DEBUG) {
98  CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path);
99  }
100 
101  driver->flag |= DRIVER_FLAG_INVALID;
102  dtar->flag |= DTAR_FLAG_INVALID;
103  return 0.0f;
104  }
105 
106  /* Get RNA-pointer for the ID-block given in target. */
107  RNA_id_pointer_create(id, &id_ptr);
108 
109  /* Get property to read from, and get value as appropriate. */
110  if (!RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
111  /* Path couldn't be resolved. */
112  if (G.debug & G_DEBUG) {
113  CLOG_ERROR(&LOG,
114  "Driver Evaluation Error: cannot resolve target for %s -> %s",
115  id->name,
116  dtar->rna_path);
117  }
118 
119  driver->flag |= DRIVER_FLAG_INVALID;
120  dtar->flag |= DTAR_FLAG_INVALID;
121  return 0.0f;
122  }
123 
124  if (RNA_property_array_check(prop)) {
125  /* Array. */
126  if (index < 0 || index >= RNA_property_array_length(&ptr, prop)) {
127  /* Out of bounds. */
128  if (G.debug & G_DEBUG) {
129  CLOG_ERROR(&LOG,
130  "Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)",
131  id->name,
132  dtar->rna_path,
133  index);
134  }
135 
136  driver->flag |= DRIVER_FLAG_INVALID;
137  dtar->flag |= DTAR_FLAG_INVALID;
138  return 0.0f;
139  }
140 
141  switch (RNA_property_type(prop)) {
142  case PROP_BOOLEAN:
143  value = (float)RNA_property_boolean_get_index(&ptr, prop, index);
144  break;
145  case PROP_INT:
146  value = (float)RNA_property_int_get_index(&ptr, prop, index);
147  break;
148  case PROP_FLOAT:
149  value = RNA_property_float_get_index(&ptr, prop, index);
150  break;
151  default:
152  break;
153  }
154  }
155  else {
156  /* Not an array. */
157  switch (RNA_property_type(prop)) {
158  case PROP_BOOLEAN:
159  value = (float)RNA_property_boolean_get(&ptr, prop);
160  break;
161  case PROP_INT:
162  value = (float)RNA_property_int_get(&ptr, prop);
163  break;
164  case PROP_FLOAT:
165  value = RNA_property_float_get(&ptr, prop);
166  break;
167  case PROP_ENUM:
168  value = (float)RNA_property_enum_get(&ptr, prop);
169  break;
170  default:
171  break;
172  }
173  }
174 
175  /* If we're still here, we should be ok. */
176  dtar->flag &= ~DTAR_FLAG_INVALID;
177  return value;
178 }
179 
181  DriverTarget *dtar,
182  PointerRNA *r_ptr,
183  PropertyRNA **r_prop,
184  int *r_index)
185 {
186  PointerRNA id_ptr;
187  PointerRNA ptr;
188  PropertyRNA *prop;
189  ID *id;
190  int index = -1;
191 
192  /* Sanity check. */
193  if (ELEM(NULL, driver, dtar)) {
194  return false;
195  }
196 
197  id = dtar->id;
198 
199  /* Error check for missing pointer. */
200  if (id == NULL) {
201  if (G.debug & G_DEBUG) {
202  CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path);
203  }
204 
205  driver->flag |= DRIVER_FLAG_INVALID;
206  dtar->flag |= DTAR_FLAG_INVALID;
207  return false;
208  }
209 
210  /* Get RNA-pointer for the ID-block given in target. */
211  RNA_id_pointer_create(id, &id_ptr);
212 
213  /* Get property to read from, and get value as appropriate. */
214  if (dtar->rna_path == NULL || dtar->rna_path[0] == '\0') {
216  prop = NULL; /* OK. */
217  }
218  else if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
219  /* OK. */
220  }
221  else {
222  /* Path couldn't be resolved. */
223  if (G.debug & G_DEBUG) {
224  CLOG_ERROR(&LOG,
225  "Driver Evaluation Error: cannot resolve target for %s -> %s",
226  id->name,
227  dtar->rna_path);
228  }
229 
231  *r_prop = NULL;
232  *r_index = -1;
233 
234  driver->flag |= DRIVER_FLAG_INVALID;
235  dtar->flag |= DTAR_FLAG_INVALID;
236  return false;
237  }
238 
239  *r_ptr = ptr;
240  *r_prop = prop;
241  *r_index = index;
242 
243  /* If we're still here, we should be ok. */
244  dtar->flag &= ~DTAR_FLAG_INVALID;
245  return true;
246 }
247 
249 {
250  short valid_targets = 0;
251 
253  Object *ob = (Object *)dtar->id;
254 
255  /* Check if this target has valid data. */
256  if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
257  /* Invalid target, so will not have enough targets. */
258  driver->flag |= DRIVER_FLAG_INVALID;
259  dtar->flag |= DTAR_FLAG_INVALID;
260  }
261  else {
262  /* Target seems to be OK now. */
263  dtar->flag &= ~DTAR_FLAG_INVALID;
264  valid_targets++;
265  }
266  }
268 
269  return valid_targets;
270 }
271 
274 /* -------------------------------------------------------------------- */
278 /* Evaluate 'single prop' driver variable. */
279 static float dvar_eval_singleProp(ChannelDriver *driver, DriverVar *dvar)
280 {
281  /* Just evaluate the first target slot. */
282  return dtar_get_prop_val(driver, &dvar->targets[0]);
283 }
284 
285 /* Evaluate 'rotation difference' driver variable. */
286 static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
287 {
288  short valid_targets = driver_check_valid_targets(driver, dvar);
289 
290  /* Make sure we have enough valid targets to use - all or nothing for now. */
291  if (driver_check_valid_targets(driver, dvar) != 2) {
292  if (G.debug & G_DEBUG) {
293  CLOG_WARN(&LOG,
294  "RotDiff DVar: not enough valid targets (n = %d) (a = %p, b = %p)",
295  valid_targets,
296  dvar->targets[0].id,
297  dvar->targets[1].id);
298  }
299  return 0.0f;
300  }
301 
302  float(*mat[2])[4];
303 
304  /* NOTE: for now, these are all just world-space. */
305  for (int i = 0; i < 2; i++) {
306  /* Get pointer to loc values to store in. */
307  DriverTarget *dtar = &dvar->targets[i];
308  Object *ob = (Object *)dtar->id;
309  bPoseChannel *pchan;
310 
311  /* After the checks above, the targets should be valid here. */
312  BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB));
313 
314  /* Try to get pose-channel. */
315  pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
316 
317  /* Check if object or bone. */
318  if (pchan) {
319  /* Bone. */
320  mat[i] = pchan->pose_mat;
321  }
322  else {
323  /* Object. */
324  mat[i] = ob->obmat;
325  }
326  }
327 
328  float q1[4], q2[4], quat[4], angle;
329 
330  /* Use the final posed locations. */
331  mat4_to_quat(q1, mat[0]);
332  mat4_to_quat(q2, mat[1]);
333 
335  mul_qt_qtqt(quat, q1, q2);
336  angle = 2.0f * (saacos(quat[0]));
337  angle = fabsf(angle);
338 
339  return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle);
340 }
341 
347 static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
348 {
349  float loc1[3] = {0.0f, 0.0f, 0.0f};
350  float loc2[3] = {0.0f, 0.0f, 0.0f};
351  short valid_targets = driver_check_valid_targets(driver, dvar);
352 
353  /* Make sure we have enough valid targets to use - all or nothing for now. */
354  if (valid_targets < dvar->num_targets) {
355  if (G.debug & G_DEBUG) {
356  CLOG_WARN(&LOG,
357  "LocDiff DVar: not enough valid targets (n = %d) (a = %p, b = %p)",
358  valid_targets,
359  dvar->targets[0].id,
360  dvar->targets[1].id);
361  }
362  return 0.0f;
363  }
364 
365  /* SECOND PASS: get two location values */
366  /* NOTE: for now, these are all just world-space */
368  /* Get pointer to loc values to store in. */
369  Object *ob = (Object *)dtar->id;
370  bPoseChannel *pchan;
371  float tmp_loc[3];
372 
373  /* After the checks above, the targets should be valid here. */
374  BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB));
375 
376  /* Try to get pose-channel. */
377  pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
378 
379  /* Check if object or bone. */
380  if (pchan) {
381  /* Bone. */
382  if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
383  if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
384  float mat[4][4];
385 
386  /* Extract transform just like how the constraints do it! */
387  copy_m4_m4(mat, pchan->pose_mat);
389  ob, pchan, NULL, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
390 
391  /* ... and from that, we get our transform. */
392  copy_v3_v3(tmp_loc, mat[3]);
393  }
394  else {
395  /* Transform space (use transform values directly). */
396  copy_v3_v3(tmp_loc, pchan->loc);
397  }
398  }
399  else {
400  /* Convert to world-space. */
401  copy_v3_v3(tmp_loc, pchan->pose_head);
402  mul_m4_v3(ob->obmat, tmp_loc);
403  }
404  }
405  else {
406  /* Object. */
407  if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
408  if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
409  /* XXX: this should practically be the same as transform space. */
410  float mat[4][4];
411 
412  /* Extract transform just like how the constraints do it! */
413  copy_m4_m4(mat, ob->obmat);
416 
417  /* ... and from that, we get our transform. */
418  copy_v3_v3(tmp_loc, mat[3]);
419  }
420  else {
421  /* Transform space (use transform values directly). */
422  copy_v3_v3(tmp_loc, ob->loc);
423  }
424  }
425  else {
426  /* World-space. */
427  copy_v3_v3(tmp_loc, ob->obmat[3]);
428  }
429  }
430 
431  /* Copy the location to the right place. */
432  if (tarIndex) {
433  copy_v3_v3(loc2, tmp_loc);
434  }
435  else {
436  copy_v3_v3(loc1, tmp_loc);
437  }
438  }
440 
441  /* If we're still here, there should now be two targets to use,
442  * so just take the length of the vector between these points. */
443  return len_v3v3(loc1, loc2);
444 }
445 
449 static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
450 {
451  DriverTarget *dtar = &dvar->targets[0];
452  Object *ob = (Object *)dtar->id;
453  bPoseChannel *pchan;
454  float mat[4][4];
455  float oldEul[3] = {0.0f, 0.0f, 0.0f};
456  bool use_eulers = false;
457  short rot_order = ROT_MODE_EUL;
458 
459  /* Check if this target has valid data. */
460  if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
461  /* Invalid target, so will not have enough targets. */
462  driver->flag |= DRIVER_FLAG_INVALID;
463  dtar->flag |= DTAR_FLAG_INVALID;
464  return 0.0f;
465  }
466 
467  /* Target should be valid now. */
468  dtar->flag &= ~DTAR_FLAG_INVALID;
469 
470  /* Try to get pose-channel. */
471  pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
472 
473  /* Check if object or bone, and get transform matrix accordingly:
474  * - "use_eulers" code is used to prevent the problems associated with non-uniqueness
475  * of euler decomposition from matrices T20870.
476  * - "local-space" is for T21384, where parent results are not wanted
477  * but #DTAR_FLAG_LOCAL_CONSTS is for all the common "corrective-shapes-for-limbs" situations.
478  */
479  if (pchan) {
480  /* Bone. */
481  if (pchan->rotmode > 0) {
482  copy_v3_v3(oldEul, pchan->eul);
483  rot_order = pchan->rotmode;
484  use_eulers = true;
485  }
486 
487  if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
488  if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
489  /* Just like how the constraints do it! */
490  copy_m4_m4(mat, pchan->pose_mat);
492  ob, pchan, NULL, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
493  }
494  else {
495  /* Specially calculate local matrix, since chan_mat is not valid
496  * since it stores delta transform of pose_mat so that deforms work
497  * so it cannot be used here for "transform" space. */
498  BKE_pchan_to_mat4(pchan, mat);
499  }
500  }
501  else {
502  /* World-space matrix. */
503  mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
504  }
505  }
506  else {
507  /* Object. */
508  if (ob->rotmode > 0) {
509  copy_v3_v3(oldEul, ob->rot);
510  rot_order = ob->rotmode;
511  use_eulers = true;
512  }
513 
514  if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
515  if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
516  /* Just like how the constraints do it! */
517  copy_m4_m4(mat, ob->obmat);
520  }
521  else {
522  /* Transforms to matrix. */
523  BKE_object_to_mat4(ob, mat);
524  }
525  }
526  else {
527  /* World-space matrix - just the good-old one. */
528  copy_m4_m4(mat, ob->obmat);
529  }
530  }
531 
532  /* Check which transform. */
533  if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) {
534  /* Not valid channel. */
535  return 0.0f;
536  }
537  if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) {
538  /* Cubic root of the change in volume, equal to the geometric mean
539  * of scale over all three axes unless the matrix includes shear. */
540  return cbrtf(mat4_to_volume_scale(mat));
541  }
543  /* Extract scale, and choose the right axis,
544  * inline 'mat4_to_size'. */
545  return len_v3(mat[dtar->transChan - DTAR_TRANSCHAN_SCALEX]);
546  }
547  if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
548  /* Extract rotation as eulers (if needed)
549  * - definitely if rotation order isn't eulers already
550  * - if eulers, then we have 2 options:
551  * a) decompose transform matrix as required, then try to make eulers from
552  * there compatible with original values
553  * b) [NOT USED] directly use the original values (no decomposition)
554  * - only an option for "transform space", if quality is really bad with a)
555  */
556  float quat[4];
557  int channel;
558 
559  if (dtar->transChan == DTAR_TRANSCHAN_ROTW) {
560  channel = 0;
561  }
562  else {
563  channel = 1 + dtar->transChan - DTAR_TRANSCHAN_ROTX;
564  BLI_assert(channel < 4);
565  }
566 
568  mat, rot_order, dtar->rotation_mode, channel, false, quat);
569 
570  if (use_eulers && dtar->rotation_mode == DTAR_ROTMODE_AUTO) {
571  compatible_eul(quat + 1, oldEul);
572  }
573 
574  return quat[channel];
575  }
576 
577  /* Extract location and choose right axis. */
578  return mat[3][dtar->transChan];
579 }
580 
581 /* Convert a quaternion to pseudo-angles representing the weighted amount of rotation. */
582 static void quaternion_to_angles(float quat[4], int channel)
583 {
584  if (channel < 0) {
585  quat[0] = 2.0f * saacosf(quat[0]);
586 
587  for (int i = 1; i < 4; i++) {
588  quat[i] = 2.0f * saasinf(quat[i]);
589  }
590  }
591  else if (channel == 0) {
592  quat[0] = 2.0f * saacosf(quat[0]);
593  }
594  else {
595  quat[channel] = 2.0f * saasinf(quat[channel]);
596  }
597 }
598 
600  float mat[4][4], int auto_order, int rotation_mode, int channel, bool angles, float r_buf[4])
601 {
602  float *const quat = r_buf;
603  float *const eul = r_buf + 1;
604 
605  zero_v4(r_buf);
606 
607  if (rotation_mode == DTAR_ROTMODE_AUTO) {
608  mat4_to_eulO(eul, auto_order, mat);
609  }
610  else if (rotation_mode >= DTAR_ROTMODE_EULER_MIN && rotation_mode <= DTAR_ROTMODE_EULER_MAX) {
611  mat4_to_eulO(eul, rotation_mode, mat);
612  }
613  else if (rotation_mode == DTAR_ROTMODE_QUATERNION) {
614  mat4_to_quat(quat, mat);
615 
616  /* For Transformation constraint convenience, convert to pseudo-angles. */
617  if (angles) {
618  quaternion_to_angles(quat, channel);
619  }
620  }
621  else if (rotation_mode >= DTAR_ROTMODE_SWING_TWIST_X &&
622  rotation_mode <= DTAR_ROTMODE_SWING_TWIST_Z) {
623  int axis = rotation_mode - DTAR_ROTMODE_SWING_TWIST_X;
624  float raw_quat[4], twist;
625 
626  mat4_to_quat(raw_quat, mat);
627 
628  if (channel == axis + 1) {
629  /* If only the twist angle is needed, skip computing swing. */
630  twist = quat_split_swing_and_twist(raw_quat, axis, NULL, NULL);
631  }
632  else {
633  twist = quat_split_swing_and_twist(raw_quat, axis, quat, NULL);
634 
635  quaternion_to_angles(quat, channel);
636  }
637 
638  quat[axis + 1] = twist;
639  }
640  else {
641  BLI_assert(false);
642  }
643 }
644 
647 /* -------------------------------------------------------------------- */
651 /* Table of Driver Variable Type Info Data */
654  1, /* Number of targets used. */
655  {"Property"}, /* UI names for targets */
656  {0} /* Flags. */
658 
660  2, /* Number of targets used. */
661  {"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
665 
667  2, /* Number of targets used. */
668  {"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
672 
674  1, /* Number of targets used. */
675  {"Object/Bone"}, /* UI names for targets */
678 };
679 
680 /* Get driver variable typeinfo */
682 {
683  /* Check if valid type. */
684  if ((type >= 0) && (type < MAX_DVAR_TYPES)) {
685  return &dvar_types[type];
686  }
687 
688  return NULL;
689 }
690 
693 /* -------------------------------------------------------------------- */
697 void driver_free_variable(ListBase *variables, DriverVar *dvar)
698 {
699  /* Sanity checks. */
700  if (dvar == NULL) {
701  return;
702  }
703 
704  /* Free target vars:
705  * - need to go over all of them, not just up to the ones that are used
706  * currently, since there may be some lingering RNA paths from
707  * previous users needing freeing
708  */
710  /* Free RNA path if applicable. */
711  if (dtar->rna_path) {
712  MEM_freeN(dtar->rna_path);
713  }
714  }
716 
717  /* Remove the variable from the driver. */
718  BLI_freelinkN(variables, dvar);
719 }
720 
722 {
723  /* Remove and free the driver variable. */
724  driver_free_variable(&driver->variables, dvar);
725 
726  /* Since driver variables are cached, the expression needs re-compiling too. */
727  BKE_driver_invalidate_expression(driver, false, true);
728 }
729 
730 void driver_variables_copy(ListBase *dst_vars, const ListBase *src_vars)
731 {
733  BLI_duplicatelist(dst_vars, src_vars);
734 
735  LISTBASE_FOREACH (DriverVar *, dvar, dst_vars) {
736  /* Need to go over all targets so that we don't leave any dangling paths. */
738  /* Make a copy of target's rna path if available. */
739  if (dtar->rna_path) {
740  dtar->rna_path = MEM_dupallocN(dtar->rna_path);
741  }
742  }
744  }
745 }
746 
748 {
750 
751  /* Sanity check. */
752  if (ELEM(NULL, dvar, dvti)) {
753  return;
754  }
755 
756  /* Set the new settings. */
757  dvar->type = type;
758  dvar->num_targets = dvti->num_targets;
759 
760  /* Make changes to the targets based on the defines for these types.
761  * NOTE: only need to make sure the ones we're using here are valid. */
763  short flags = dvti->target_flags[tarIndex];
764 
765  /* Store the flags. */
766  dtar->flag = flags;
767 
768  /* Object ID types only, or idtype not yet initialized. */
769  if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0)) {
770  dtar->idtype = ID_OB;
771  }
772  }
774 }
775 
777 {
778  /* Special character blacklist */
779  const char special_char_blacklist[] = {
780  '~', '`', '!', '@', '#', '$', '%', '^', '&', '*', '+', '=', '-', '/', '\\',
781  '?', ':', ';', '<', '>', '{', '}', '[', ']', '|', ' ', '.', '\t', '\n', '\r',
782  };
783 
784  /* Sanity checks. */
785  if (dvar == NULL) {
786  return;
787  }
788 
789  /* Clear all invalid-name flags. */
790  dvar->flag &= ~DVAR_ALL_INVALID_FLAGS;
791 
792  /* 0) Zero-length identifiers are not allowed */
793  if (dvar->name[0] == '\0') {
794  dvar->flag |= DVAR_FLAG_INVALID_EMPTY;
795  }
796 
797  /* 1) Must start with a letter */
798  /* XXX: We assume that valid unicode letters in other languages are ok too,
799  * hence the blacklisting. */
800  if (IN_RANGE_INCL(dvar->name[0], '0', '9')) {
802  }
803  else if (dvar->name[0] == '_') {
804  /* NOTE: We don't allow names to start with underscores
805  * (i.e. it helps when ruling out security risks) */
807  }
808 
809  /* 2) Must not contain invalid stuff in the middle of the string */
810  if (strchr(dvar->name, ' ')) {
812  }
813  if (strchr(dvar->name, '.')) {
815  }
816 
817  /* 3) Check for special characters - Either at start, or in the middle */
818  for (int i = 0; i < sizeof(special_char_blacklist); i++) {
819  char *match = strchr(dvar->name, special_char_blacklist[i]);
820 
821  if (match == dvar->name) {
823  }
824  else if (match != NULL) {
826  }
827  }
828 
829  /* 4) Check if the name is a reserved keyword
830  * NOTE: These won't confuse Python, but it will be impossible to use the variable
831  * in an expression without Python misinterpreting what these are for
832  */
833 #ifdef WITH_PYTHON
834  if (BPY_string_is_keyword(dvar->name)) {
836  }
837 #endif
838 
839  /* If any these conditions match, the name is invalid */
840  if (dvar->flag & DVAR_ALL_INVALID_FLAGS) {
841  dvar->flag |= DVAR_FLAG_INVALID_NAME;
842  }
843 }
844 
846 {
847  ListBase variables = BLI_listbase_from_link((Link *)dvar);
848  BLI_uniquename(&variables, dvar, dvar->name, '_', offsetof(DriverVar, name), sizeof(dvar->name));
849 }
850 
852 {
853  DriverVar *dvar;
854 
855  /* Sanity checks. */
856  if (driver == NULL) {
857  return NULL;
858  }
859 
860  /* Make a new variable. */
861  dvar = MEM_callocN(sizeof(DriverVar), "DriverVar");
862  BLI_addtail(&driver->variables, dvar);
863 
864  /* Give the variable a 'unique' name. */
865  strcpy(dvar->name, CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "var"));
866  BLI_uniquename(&driver->variables,
867  dvar,
869  '_',
870  offsetof(DriverVar, name),
871  sizeof(dvar->name));
872 
873  /* Set the default type to 'single prop'. */
875 
876  /* Since driver variables are cached, the expression needs re-compiling too. */
877  BKE_driver_invalidate_expression(driver, false, true);
878 
879  /* Return the target. */
880  return dvar;
881 }
882 
884 {
885  ChannelDriver *driver;
886  DriverVar *dvar, *dvarn;
887 
888  /* Sanity checks. */
889  if (ELEM(NULL, fcu, fcu->driver)) {
890  return;
891  }
892  driver = fcu->driver;
893 
894  /* Free driver targets. */
895  for (dvar = driver->variables.first; dvar; dvar = dvarn) {
896  dvarn = dvar->next;
897  driver_free_variable_ex(driver, dvar);
898  }
899 
900 #ifdef WITH_PYTHON
901  /* Free compiled driver expression. */
902  if (driver->expr_comp) {
903  BPY_DECREF(driver->expr_comp);
904  }
905 #endif
906 
908 
909  /* Free driver itself, then set F-Curve's point to this to NULL
910  * (as the curve may still be used). */
911  MEM_freeN(driver);
912  fcu->driver = NULL;
913 }
914 
916 {
917  ChannelDriver *ndriver;
918 
919  /* Sanity checks. */
920  if (driver == NULL) {
921  return NULL;
922  }
923 
924  /* Copy all data. */
925  ndriver = MEM_dupallocN(driver);
926  ndriver->expr_comp = NULL;
927  ndriver->expr_simple = NULL;
928 
929  /* Copy variables. */
930 
931  /* To get rid of refs to non-copied data (that's still used on original). */
932  BLI_listbase_clear(&ndriver->variables);
933  driver_variables_copy(&ndriver->variables, &driver->variables);
934 
935  /* Return the new driver. */
936  return ndriver;
937 }
938 
941 /* -------------------------------------------------------------------- */
945 /* Index constants for the expression parameter array. */
946 enum {
947  /* Index of the 'frame' variable. */
949  /* Index of the first user-defined driver variable. */
951 };
952 
954 {
955  /* Prepare parameter names. */
956  int names_len = BLI_listbase_count(&driver->variables);
958  int i = VAR_INDEX_CUSTOM;
959 
960  names[VAR_INDEX_FRAME] = "frame";
961 
962  LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
963  names[i++] = dvar->name;
964  }
965 
967 }
968 
970 {
971  /* Check if the 'frame' parameter is actually used. */
973 }
974 
976  ExprPyLike_Parsed *expr,
977  float *result,
978  float time)
979 {
980  /* Prepare parameter values. */
981  int vars_len = BLI_listbase_count(&driver->variables);
982  double *vars = BLI_array_alloca(vars, vars_len + VAR_INDEX_CUSTOM);
983  int i = VAR_INDEX_CUSTOM;
984 
985  vars[VAR_INDEX_FRAME] = time;
986 
987  LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
988  vars[i++] = driver_get_variable_value(driver, dvar);
989  }
990 
991  /* Evaluate expression. */
992  double result_val;
994  expr, vars, vars_len + VAR_INDEX_CUSTOM, &result_val);
995  const char *message;
996 
997  switch (status) {
998  case EXPR_PYLIKE_SUCCESS:
999  if (isfinite(result_val)) {
1000  *result = (float)result_val;
1001  }
1002  return true;
1003 
1006  message = (status == EXPR_PYLIKE_DIV_BY_ZERO) ? "Division by Zero" : "Math Domain Error";
1007  CLOG_ERROR(&LOG, "%s in Driver: '%s'", message, driver->expression);
1008 
1009  driver->flag |= DRIVER_FLAG_INVALID;
1010  return true;
1011 
1012  default:
1013  /* Arriving here means a bug, not user error. */
1014  CLOG_ERROR(&LOG, "simple driver expression evaluation failed: '%s'", driver->expression);
1015  return false;
1016  }
1017 }
1018 
1019 /* Compile and cache the driver expression if necessary, with thread safety. */
1021 {
1022  if (driver->expr_simple != NULL) {
1023  return true;
1024  }
1025 
1026  if (driver->type != DRIVER_TYPE_PYTHON) {
1027  return false;
1028  }
1029 
1030  /* It's safe to parse in multiple threads; at worst it'll
1031  * waste some effort, but in return avoids mutex contention. */
1033 
1034  /* Store the result if the field is still NULL, or discard
1035  * it if another thread got here first. */
1036  if (atomic_cas_ptr((void **)&driver->expr_simple, NULL, expr) != NULL) {
1037  BLI_expr_pylike_free(expr);
1038  }
1039 
1040  return true;
1041 }
1042 
1043 /* Try using the simple expression evaluator to compute the result of the driver.
1044  * On success, stores the result and returns true; on failure result is set to 0. */
1046  ChannelDriver *driver_orig,
1047  float *result,
1048  float time)
1049 {
1050  *result = 0.0f;
1051 
1052  return driver_compile_simple_expr(driver_orig) &&
1053  BLI_expr_pylike_is_valid(driver_orig->expr_simple) &&
1054  driver_evaluate_simple_expr(driver, driver_orig->expr_simple, result, time);
1055 }
1056 
1058 {
1060 }
1061 
1062 /* TODO(sergey): This is somewhat weak, but we don't want neither false-positive
1063  * time dependencies nor special exceptions in the depsgraph evaluation. */
1064 static bool python_driver_exression_depends_on_time(const char *expression)
1065 {
1066  if (expression[0] == '\0') {
1067  /* Empty expression depends on nothing. */
1068  return false;
1069  }
1070  if (strchr(expression, '(') != NULL) {
1071  /* Function calls are considered dependent on a time. */
1072  return true;
1073  }
1074  if (strstr(expression, "frame") != NULL) {
1075  /* Variable `frame` depends on time. */
1076  /* TODO(sergey): This is a bit weak, but not sure about better way of handling this. */
1077  return true;
1078  }
1079  /* Possible indirect time relation s should be handled via variable targets. */
1080  return false;
1081 }
1082 
1084 {
1085  if (driver->type != DRIVER_TYPE_PYTHON) {
1086  return false;
1087  }
1088 
1089  if (BKE_driver_has_simple_expression(driver)) {
1090  /* Simple expressions can be checked exactly. */
1092  }
1093 
1094  /* Otherwise, heuristically scan the expression string for certain patterns. */
1096 }
1097 
1099  bool expr_changed,
1100  bool varname_changed)
1101 {
1102  if (expr_changed || varname_changed) {
1104  driver->expr_simple = NULL;
1105  }
1106 
1107 #ifdef WITH_PYTHON
1108  if (expr_changed) {
1109  driver->flag |= DRIVER_FLAG_RECOMPILE;
1110  }
1111 
1112  if (varname_changed) {
1113  driver->flag |= DRIVER_FLAG_RENAMEVAR;
1114  }
1115 #endif
1116 }
1117 
1120 /* -------------------------------------------------------------------- */
1125 {
1126  const DriverVarTypeInfo *dvti;
1127 
1128  /* Sanity check. */
1129  if (ELEM(NULL, driver, dvar)) {
1130  return 0.0f;
1131  }
1132 
1133  /* Call the relevant callbacks to get the variable value
1134  * using the variable type info, storing the obtained value
1135  * in `dvar->curval` so that drivers can be debugged. */
1136  dvti = get_dvar_typeinfo(dvar->type);
1137 
1138  if (dvti && dvti->get_value) {
1139  dvar->curval = dvti->get_value(driver, dvar);
1140  }
1141  else {
1142  dvar->curval = 0.0f;
1143  }
1144 
1145  return dvar->curval;
1146 }
1147 
1149 {
1150  DriverVar *dvar;
1151 
1152  /* Check how many variables there are first (i.e. just one?). */
1153  if (BLI_listbase_is_single(&driver->variables)) {
1154  /* Just one target, so just use that. */
1155  dvar = driver->variables.first;
1156  driver->curval = driver_get_variable_value(driver, dvar);
1157  return;
1158  }
1159 
1160  /* More than one target, so average the values of the targets. */
1161  float value = 0.0f;
1162  int tot = 0;
1163 
1164  /* Loop through targets, adding (hopefully we don't get any overflow!). */
1165  for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
1166  value += driver_get_variable_value(driver, dvar);
1167  tot++;
1168  }
1169 
1170  /* Perform operations on the total if appropriate. */
1171  if (driver->type == DRIVER_TYPE_AVERAGE) {
1172  driver->curval = tot ? (value / (float)tot) : 0.0f;
1173  }
1174  else {
1175  driver->curval = value;
1176  }
1177 }
1178 
1180 {
1181  DriverVar *dvar;
1182  float value = 0.0f;
1183 
1184  /* Loop through the variables, getting the values and comparing them to existing ones. */
1185  for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
1186  /* Get value. */
1187  float tmp_val = driver_get_variable_value(driver, dvar);
1188 
1189  /* Store this value if appropriate. */
1190  if (dvar->prev) {
1191  /* Check if greater/smaller than the baseline. */
1192  if (driver->type == DRIVER_TYPE_MAX) {
1193  /* Max? */
1194  if (tmp_val > value) {
1195  value = tmp_val;
1196  }
1197  }
1198  else {
1199  /* Min? */
1200  if (tmp_val < value) {
1201  value = tmp_val;
1202  }
1203  }
1204  }
1205  else {
1206  /* First item - make this the baseline for comparisons. */
1207  value = tmp_val;
1208  }
1209  }
1210 
1211  /* Store value in driver. */
1212  driver->curval = value;
1213 }
1214 
1216  ChannelDriver *driver,
1217  ChannelDriver *driver_orig,
1218  const AnimationEvalContext *anim_eval_context)
1219 {
1220  /* Check for empty or invalid expression. */
1221  if ((driver_orig->expression[0] == '\0') || (driver_orig->flag & DRIVER_FLAG_INVALID)) {
1222  driver->curval = 0.0f;
1223  }
1225  driver, driver_orig, &driver->curval, anim_eval_context->eval_time)) {
1226 #ifdef WITH_PYTHON
1227  /* This evaluates the expression using Python, and returns its result:
1228  * - on errors it reports, then returns 0.0f. */
1229  BLI_mutex_lock(&python_driver_lock);
1230 
1231  driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, anim_eval_context);
1232 
1233  BLI_mutex_unlock(&python_driver_lock);
1234 #else /* WITH_PYTHON */
1235  UNUSED_VARS(anim_rna, anim_eval_context);
1236 #endif /* WITH_PYTHON */
1237  }
1238 }
1239 
1241  ChannelDriver *driver,
1242  ChannelDriver *driver_orig,
1243  const AnimationEvalContext *anim_eval_context)
1244 {
1245  /* Check if driver can be evaluated. */
1246  if (driver_orig->flag & DRIVER_FLAG_INVALID) {
1247  return 0.0f;
1248  }
1249 
1250  switch (driver->type) {
1251  case DRIVER_TYPE_AVERAGE: /* Average values of driver targets. */
1252  case DRIVER_TYPE_SUM: /* Sum values of driver targets. */
1253  evaluate_driver_sum(driver);
1254  break;
1255  case DRIVER_TYPE_MIN: /* Smallest value. */
1256  case DRIVER_TYPE_MAX: /* Largest value. */
1257  evaluate_driver_min_max(driver);
1258  break;
1259  case DRIVER_TYPE_PYTHON: /* Expression. */
1260  evaluate_driver_python(anim_rna, driver, driver_orig, anim_eval_context);
1261  break;
1262  default:
1263  /* Special 'hack' - just use stored value
1264  * This is currently used as the mechanism which allows animated settings to be able
1265  * to be changed via the UI. */
1266  break;
1267  }
1268 
1269  /* Return value for driver. */
1270  return driver->curval;
1271 }
1272 
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
void BKE_pchan_to_mat4(const struct bPoseChannel *pchan, float r_chanmat[4][4])
void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, struct bConstraintOb *cob, float mat[4][4], short from, short to, bool keep_scale)
Definition: constraint.c:245
#define DRIVER_TARGETS_LOOPER_BEGIN(dvar)
#define DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
#define DRIVER_TARGETS_LOOPER_END
@ G_DEBUG
Definition: BKE_global.h:174
General operations, lookup, etc. for blender objects.
void BKE_object_to_mat4(struct Object *ob, float r_mat[4][4])
Definition: object.cc:3082
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:22
#define BLI_assert(a)
Definition: BLI_assert.h:46
eExprPyLike_EvalStatus
@ EXPR_PYLIKE_SUCCESS
@ EXPR_PYLIKE_DIV_BY_ZERO
@ EXPR_PYLIKE_MATH_ERROR
eExprPyLike_EvalStatus BLI_expr_pylike_eval(struct ExprPyLike_Parsed *expr, const double *param_values, int param_values_len, double *r_result)
ExprPyLike_Parsed * BLI_expr_pylike_parse(const char *expression, const char **param_names, int param_names_len)
void BLI_expr_pylike_free(struct ExprPyLike_Parsed *expr)
bool BLI_expr_pylike_is_using_param(struct ExprPyLike_Parsed *expr, int index)
bool BLI_expr_pylike_is_valid(struct ExprPyLike_Parsed *expr)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
Definition: BLI_listbase.h:265
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
ListBase BLI_listbase_from_link(struct Link *some_link)
Definition: listbase.c:761
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float saacos(float fac)
MINLINE float saasinf(float f)
MINLINE float saacosf(float f)
#define M_PI
Definition: BLI_math_base.h:20
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
float mat4_to_volume_scale(const float M[4][4])
Definition: math_matrix.c:2171
void invert_qt_normalized(float q[4])
void mat4_to_eulO(float eul[3], short order, const float mat[4][4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:46
void mat4_to_quat(float q[4], const float mat[4][4])
void compatible_eul(float eul[3], const float old[3])
float quat_split_swing_and_twist(const float q[4], int axis, float r_swing[4], float r_twist[4])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v4(float r[4])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_len)
Definition: string_utils.c:309
#define BLI_MUTEX_INITIALIZER
Definition: BLI_threads.h:83
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:373
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:378
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:82
#define UNUSED_VARS(...)
#define ELEM(...)
#define IN_RANGE_INCL(a, b, c)
#define BLT_I18NCONTEXT_ID_ACTION
#define CTX_DATA_(context, msgid)
bool BPY_string_is_keyword(const char *str)
float BPY_driver_exec(struct PathResolvedRNA *anim_rna, struct ChannelDriver *driver, struct ChannelDriver *driver_orig, const struct AnimationEvalContext *anim_eval_context)
void BPY_DECREF(void *pyob_ptr)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:189
@ ID_OB
Definition: DNA_ID_enums.h:47
@ ROT_MODE_EUL
#define MAX_DRIVER_TARGETS
@ DTAR_TRANSCHAN_SCALEX
@ DTAR_TRANSCHAN_SCALEZ
@ DTAR_TRANSCHAN_ROTW
@ DTAR_TRANSCHAN_ROTX
@ MAX_DTAR_TRANSCHAN_TYPES
@ DTAR_TRANSCHAN_SCALE_AVG
@ DTAR_TRANSCHAN_SCALEY
@ DRIVER_TYPE_AVERAGE
@ DRIVER_TYPE_PYTHON
@ DRIVER_TYPE_MAX
@ DRIVER_TYPE_MIN
@ DRIVER_TYPE_SUM
@ DVAR_TYPE_LOC_DIFF
@ DVAR_TYPE_TRANSFORM_CHAN
@ DVAR_TYPE_ROT_DIFF
@ MAX_DVAR_TYPES
@ DVAR_TYPE_SINGLE_PROP
@ DTAR_ROTMODE_QUATERNION
@ DTAR_ROTMODE_SWING_TWIST_X
@ DTAR_ROTMODE_EULER_MIN
@ DTAR_ROTMODE_AUTO
@ DTAR_ROTMODE_EULER_MAX
@ DTAR_ROTMODE_SWING_TWIST_Z
@ DTAR_FLAG_LOCAL_CONSTS
@ DTAR_FLAG_LOCALSPACE
@ DTAR_FLAG_ID_OB_ONLY
@ DTAR_FLAG_INVALID
@ DTAR_FLAG_STRUCT_REF
@ DRIVER_FLAG_INVALID
@ DRIVER_FLAG_RECOMPILE
@ DRIVER_FLAG_RENAMEVAR
#define DVAR_ALL_INVALID_FLAGS
@ DVAR_FLAG_INVALID_START_CHAR
@ DVAR_FLAG_INVALID_NAME
@ DVAR_FLAG_INVALID_EMPTY
@ DVAR_FLAG_INVALID_START_NUM
@ DVAR_FLAG_INVALID_HAS_SPACE
@ DVAR_FLAG_INVALID_HAS_DOT
@ DVAR_FLAG_INVALID_HAS_SPECIAL
@ DVAR_FLAG_INVALID_PY_KEYWORD
@ CONSTRAINT_SPACE_POSE
@ CONSTRAINT_SPACE_WORLD
@ CONSTRAINT_SPACE_LOCAL
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
@ PROP_FLOAT
Definition: RNA_types.h:61
@ PROP_BOOLEAN
Definition: RNA_types.h:59
@ PROP_ENUM
Definition: RNA_types.h:63
@ PROP_INT
Definition: RNA_types.h:60
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE void * atomic_cas_ptr(void **v, void *old, void *_new)
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
double time
void driver_change_variable_type(DriverVar *dvar, int type)
static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
static void evaluate_driver_min_max(ChannelDriver *driver)
void fcurve_free_driver(FCurve *fcu)
static ExprPyLike_Parsed * driver_compile_simple_expr_impl(ChannelDriver *driver)
static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
bool driver_get_variable_property(ChannelDriver *driver, DriverTarget *dtar, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
bool BKE_driver_expression_depends_on_time(ChannelDriver *driver)
float evaluate_driver(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context)
void BKE_driver_target_matrix_to_rot_channels(float mat[4][4], int auto_order, int rotation_mode, int channel, bool angles, float r_buf[4])
static float dvar_eval_singleProp(ChannelDriver *driver, DriverVar *dvar)
static void evaluate_driver_python(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context)
static bool python_driver_exression_depends_on_time(const char *expression)
void driver_free_variable(ListBase *variables, DriverVar *dvar)
static const DriverVarTypeInfo * get_dvar_typeinfo(int type)
static void evaluate_driver_sum(ChannelDriver *driver)
void driver_variable_unique_name(DriverVar *dvar)
struct DriverVarTypeInfo DriverVarTypeInfo
void driver_variable_name_validate(DriverVar *dvar)
void driver_variables_copy(ListBase *dst_vars, const ListBase *src_vars)
ChannelDriver * fcurve_copy_driver(const ChannelDriver *driver)
static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
@ VAR_INDEX_FRAME
@ VAR_INDEX_CUSTOM
#define END_DVAR_TYPEDEF
Definition: fcurve_driver.c:68
static bool driver_compile_simple_expr(ChannelDriver *driver)
static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
DriverVar * driver_add_new_variable(ChannelDriver *driver)
static bool driver_check_simple_expr_depends_on_time(ExprPyLike_Parsed *expr)
static CLG_LogRef LOG
Definition: fcurve_driver.c:47
static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
Definition: fcurve_driver.c:80
#define BEGIN_DVAR_TYPEDEF(type)
Definition: fcurve_driver.c:65
void driver_free_variable_ex(ChannelDriver *driver, DriverVar *dvar)
static bool driver_evaluate_simple_expr(ChannelDriver *driver, ExprPyLike_Parsed *expr, float *result, float time)
static bool driver_try_evaluate_simple_expr(ChannelDriver *driver, ChannelDriver *driver_orig, float *result, float time)
static void quaternion_to_angles(float quat[4], int channel)
static DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES]
bool BKE_driver_has_simple_expression(ChannelDriver *driver)
void BKE_driver_invalidate_expression(ChannelDriver *driver, bool expr_changed, bool varname_changed)
float driver_get_variable_value(ChannelDriver *driver, DriverVar *dvar)
#define GS(x)
Definition: iris.c:225
static char ** names
Definition: makesdna.c:65
static int names_len
Definition: makesdna.c:61
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
#define fabsf(x)
Definition: metal/compat.h:219
bool isfinite(uchar)
Definition: scene/image.cpp:31
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
bool RNA_property_array_check(PropertyRNA *prop)
Definition: rna_access.c:1080
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2581
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2954
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
const PointerRNA PointerRNA_NULL
Definition: rna_access.c:61
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2153
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2429
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1075
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2275
bool RNA_path_resolve_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
Definition: rna_path.cc:515
bool RNA_path_resolve_property_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
Definition: rna_path.cc:543
ListBase variables
char expression[256]
struct ExprPyLike_Parsed * expr_simple
char pchan_name[64]
short target_flags[MAX_DRIVER_TARGETS]
Definition: fcurve_driver.c:61
float(* get_value)(ChannelDriver *driver, DriverVar *dvar)
Definition: fcurve_driver.c:56
const char * target_names[MAX_DRIVER_TARGETS]
Definition: fcurve_driver.c:60
struct DriverVar * next
char num_targets
DriverTarget targets[8]
char name[64]
struct DriverVar * prev
ChannelDriver * driver
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
struct bPose * pose
float loc[3]
float obmat[4][4]
PointerRNA * ptr
Definition: wm_files.c:3480