40#include "RNA_prototypes.hh"
78#define BEGIN_DVAR_TYPEDEF(type) {
81#define END_DVAR_TYPEDEF }
97 return driver_target_context;
113 &driver_target_context->
scene->
id, &RNA_ViewLayer, driver_target_context->
view_layer);
124 r_property_ptr->
data =
nullptr;
125 r_property_ptr->
type =
nullptr;
140 if (dtar->
id ==
nullptr) {
159 dtar->
flag &= ~DTAR_FLAG_INVALID;
174 if (driver ==
nullptr) {
178 dtar->
flag &= ~DTAR_FLAG_FALLBACK_USED;
202 &property_ptr, dtar->
rna_path, &value_ptr, &value_prop, &index))
211 "Driver Evaluation Error: cannot resolve target for %s -> %s",
231 "Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)",
277 dtar->
flag &= ~DTAR_FLAG_INVALID;
286 const bool allow_no_index,
296 if (
ELEM(
nullptr, driver, dtar)) {
300 dtar->
flag &= ~DTAR_FLAG_FALLBACK_USED;
335 "Driver Evaluation Error: cannot resolve target for %s -> %s",
363 "Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)",
376 dtar->
flag &= ~DTAR_FLAG_INVALID;
382 short valid_targets = 0;
395 dtar->flag &= ~DTAR_FLAG_INVALID;
401 return valid_targets;
430 "RotDiff DVar: not enough valid targets (n = %d) (a = %p, b = %p)",
438 const float(*mat[2])[4];
441 for (
int i = 0; i < 2; i++) {
460 mat[i] = ob->object_to_world().ptr();
464 float q1[4], q2[4], quat[4],
angle;
473 angle =
fabsf(angle);
487 float loc1[3] = {0.0f, 0.0f, 0.0f};
488 float loc2[3] = {0.0f, 0.0f, 0.0f};
492 if (valid_targets < dvar->num_targets) {
495 "LocDiff DVar: not enough valid targets (n = %d) (a = %p, b = %p)",
540 mul_m4_v3(ob->object_to_world().ptr(), tmp_loc);
565 copy_v3_v3(tmp_loc, ob->object_to_world().location());
595 float oldEul[3] = {0.0f, 0.0f, 0.0f};
596 bool use_eulers =
false;
616 dtar->
flag &= ~DTAR_FLAG_INVALID;
719 return quat[channel];
741 for (
int i = 1; i < 4; i++) {
745 else if (channel == 0) {
749 quat[channel] = 2.0f *
safe_asinf(quat[channel]);
754 float mat[4][4],
int auto_order,
int rotation_mode,
int channel,
bool angles,
float r_buf[4])
756 float *
const quat = r_buf;
757 float *
const eul = r_buf + 1;
779 float raw_quat[4], twist;
783 if (channel == axis + 1) {
793 quat[axis + 1] = twist;
816 {
"Object/Bone 1",
"Object/Bone 2"},
823 {
"Object/Bone 1",
"Object/Bone 2"},
861 if (dvar ==
nullptr) {
872 if (dtar->rna_path) {
900 if (dtar->rna_path) {
901 dtar->rna_path =
static_cast<char *
>(
MEM_dupallocN(dtar->rna_path));
913 if (
ELEM(
nullptr, dvar, dvti)) {
931 dtar->idtype =
ID_OB;
940 const char special_char_blacklist[] = {
941 '~',
'`',
'!',
'@',
'#',
'$',
'%',
'^',
'&',
'*',
'+',
'=',
'-',
'/',
'\\',
942 '?',
':',
';',
'<',
'>',
'{',
'}',
'[',
']',
'|',
' ',
'.',
'\t',
'\n',
'\r',
946 if (dvar ==
nullptr) {
951 dvar->
flag &= ~DVAR_ALL_INVALID_FLAGS;
954 if (dvar->
name[0] ==
'\0') {
964 else if (dvar->
name[0] ==
'_') {
971 if (strchr(dvar->
name,
' ')) {
974 if (strchr(dvar->
name,
'.')) {
979 for (
int i = 0; i <
sizeof(special_char_blacklist); i++) {
980 char *match = strchr(dvar->
name, special_char_blacklist[i]);
982 if (match == dvar->
name) {
985 else if (match !=
nullptr) {
1017 if (driver ==
nullptr) {
1032 sizeof(dvar->
name));
1081 if (driver ==
nullptr) {
1118 const char **names =
static_cast<const char **
>(
1125 names[i++] = dvar->name;
1158 const char *message;
1162 if (isfinite(result_val)) {
1163 *result =
float(result_val);
1219 anim_eval_context, driver, driver_orig->
expr_simple, result, time);
1231 if (expression[0] ==
'\0') {
1235 if (strchr(expression,
'(') !=
nullptr) {
1239 if (strstr(expression,
"frame") !=
nullptr) {
1265 bool varname_changed)
1267 if (expr_changed || varname_changed) {
1277 if (varname_changed) {
1296 if (
ELEM(
nullptr, driver, dvar)) {
1340 driver->
curval = tot ? (value /
float(tot)) : 0.0f;
1362 if (tmp_val > value) {
1368 if (tmp_val < value) {
1422 switch (driver->
type) {
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_pchan_to_mat4(const 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)
#define DRIVER_TARGETS_LOOPER_BEGIN(dvar)
eDriverVariablePropertyResult
@ DRIVER_VAR_PROPERTY_SUCCESS
@ DRIVER_VAR_PROPERTY_FALLBACK
@ DRIVER_VAR_PROPERTY_INVALID_INDEX
@ DRIVER_VAR_PROPERTY_INVALID
#define DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
#define DRIVER_TARGETS_LOOPER_END
General operations, lookup, etc. for blender objects.
void BKE_object_to_mat4(const Object *ob, float r_mat[4][4])
#define BLI_array_alloca(arr, realsize)
#define BLI_assert_unreachable()
@ EXPR_PYLIKE_DIV_BY_ZERO
eExprPyLike_EvalStatus BLI_expr_pylike_eval(struct ExprPyLike_Parsed *expr, const double *param_values, int param_values_len, double *r_result)
void BLI_expr_pylike_free(struct ExprPyLike_Parsed *expr)
bool BLI_expr_pylike_is_valid(const struct ExprPyLike_Parsed *expr)
ExprPyLike_Parsed * BLI_expr_pylike_parse(const char *expression, const char **param_names, int param_names_len)
bool BLI_expr_pylike_is_using_param(const struct ExprPyLike_Parsed *expr, int index)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void 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)
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
ListBase BLI_listbase_from_link(struct Link *some_link)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float safe_acosf(float a)
MINLINE float safe_asinf(float a)
float mat4_to_volume_scale(const float mat[4][4])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void invert_qt_normalized(float q[4])
void mat4_to_eulO(float eul[3], short order, const float m[4][4])
float quat_split_swing_and_twist(const float q_in[4], int axis, float r_swing[4], float r_twist[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
void mat4_to_quat(float q[4], const float mat[4][4])
void compatible_eul(float eul[3], const float oldrot[3])
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
#define STRNCPY_UTF8(dst, src)
void BLI_uniquename(const struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_maxncpy) ATTR_NONNULL(1
#define BLI_MUTEX_INITIALIZER
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
pthread_mutex_t ThreadMutex
#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(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context)
void BPY_DECREF(void *pyob_ptr)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
#define MAX_DRIVER_TARGETS
@ MAX_DTAR_TRANSCHAN_TYPES
@ DTAR_TRANSCHAN_SCALE_AVG
@ DTAR_OPTION_USE_FALLBACK
@ DVAR_TYPE_TRANSFORM_CHAN
@ DTAR_ROTMODE_QUATERNION
@ DTAR_ROTMODE_SWING_TWIST_X
@ DTAR_ROTMODE_SWING_TWIST_Z
@ DTAR_FLAG_FALLBACK_USED
#define DVAR_ALL_INVALID_FLAGS
@ DTAR_CONTEXT_PROPERTY_ACTIVE_SCENE
@ DTAR_CONTEXT_PROPERTY_ACTIVE_VIEW_LAYER
@ DVAR_FLAG_INVALID_START_CHAR
@ 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
Object is a sort of wrapper for general info.
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
constexpr PointerRNA PointerRNA_NULL
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)
draw_view in_light_buf[] float
static float dvar_eval_transChan(const AnimationEvalContext *, ChannelDriver *driver, DriverVar *dvar)
void driver_change_variable_type(DriverVar *dvar, int type)
static float dvar_eval_singleProp(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar)
static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
static bool driver_try_evaluate_simple_expr(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, ChannelDriver *driver_orig, float *result, float time)
void fcurve_free_driver(FCurve *fcu)
static bool driver_evaluate_simple_expr(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, ExprPyLike_Parsed *expr, float *result, float time)
static DriverTargetContext driver_target_context_from_animation_context(const AnimationEvalContext *anim_eval_context)
static void evaluate_driver_sum(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver)
bool BKE_driver_expression_depends_on_time(ChannelDriver *driver)
ChannelDriver * fcurve_copy_driver(const ChannelDriver *driver)
static bool driver_get_target_context_property(const DriverTargetContext *driver_target_context, DriverTarget *dtar, PointerRNA *r_property_ptr)
DriverVar * driver_add_new_variable(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_rotDiff(const AnimationEvalContext *, ChannelDriver *driver, DriverVar *dvar)
static const DriverVarTypeInfo * get_dvar_typeinfo(int type)
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)
eDriverVariablePropertyResult driver_get_variable_property(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar, DriverTarget *dtar, const bool allow_no_index, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
static float dvar_eval_locDiff(const AnimationEvalContext *, ChannelDriver *driver, DriverVar *dvar)
void driver_variable_unique_name(DriverVar *dvar)
static bool dtar_try_use_fallback(DriverTarget *dtar)
static float dtar_get_prop_val(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar, DriverTarget *dtar)
void driver_variable_name_validate(DriverVar *dvar)
float driver_get_variable_value(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar)
void driver_variables_copy(ListBase *dst_vars, const ListBase *src_vars)
static bool driver_compile_simple_expr(ChannelDriver *driver)
static ExprPyLike_Parsed * driver_compile_simple_expr_impl(ChannelDriver *driver)
static bool driver_check_simple_expr_depends_on_time(const ExprPyLike_Parsed *expr)
bool driver_get_target_property(const DriverTargetContext *driver_target_context, DriverVar *dvar, DriverTarget *dtar, PointerRNA *r_prop)
#define BEGIN_DVAR_TYPEDEF(type)
void driver_free_variable_ex(ChannelDriver *driver, DriverVar *dvar)
static void quaternion_to_angles(float quat[4], int channel)
static DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES]
static void evaluate_driver_min_max(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver)
bool BKE_driver_has_simple_expression(ChannelDriver *driver)
void BKE_driver_invalidate_expression(ChannelDriver *driver, bool expr_changed, bool varname_changed)
static float dvar_eval_contextProp(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_array_check(PropertyRNA *prop)
int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
PropertyType RNA_property_type(PropertyRNA *prop)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
PointerRNA RNA_id_pointer_create(ID *id)
bool RNA_path_resolve_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
bool RNA_path_resolve_property_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
struct Depsgraph * depsgraph
struct ExprPyLike_Parsed * expr_simple
struct ViewLayer * view_layer
float(* get_value)(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar)
short target_flags[MAX_DRIVER_TARGETS]
const char * target_names[MAX_DRIVER_TARGETS]