40#include "RNA_prototypes.hh"
79#define BEGIN_DVAR_TYPEDEF(type) {
82#define END_DVAR_TYPEDEF }
98 return driver_target_context;
114 &driver_target_context->
scene->
id, &RNA_ViewLayer, driver_target_context->
view_layer);
138 if (dtar->
id ==
nullptr) {
172 if (driver ==
nullptr) {
200 &property_ptr, dtar->
rna_path, &value_ptr, &value_prop, &index))
209 "Driver Evaluation Error: cannot resolve target for %s -> %s",
229 "Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)",
284 const bool allow_no_index,
294 if (
ELEM(
nullptr, driver, dtar)) {
333 "Driver Evaluation Error: cannot resolve target for %s -> %s",
361 "Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)",
380 short valid_targets = 0;
399 return valid_targets;
428 "RotDiff DVar: not enough valid targets (n = %d) (a = %p, b = %p)",
436 const float (*mat[2])[4];
439 for (
int i = 0;
i < 2;
i++) {
458 mat[
i] = ob->object_to_world().ptr();
462 float q1[4], q2[4], quat[4],
angle;
485 float loc1[3] = {0.0f, 0.0f, 0.0f};
486 float loc2[3] = {0.0f, 0.0f, 0.0f};
490 if (valid_targets < dvar->num_targets) {
493 "LocDiff DVar: not enough valid targets (n = %d) (a = %p, b = %p)",
538 mul_m4_v3(ob->object_to_world().ptr(), tmp_loc);
563 copy_v3_v3(tmp_loc, ob->object_to_world().location());
593 float oldEul[3] = {0.0f, 0.0f, 0.0f};
594 bool use_eulers =
false;
717 return quat[channel];
739 for (
int i = 1;
i < 4;
i++) {
743 else if (channel == 0) {
747 quat[channel] = 2.0f *
safe_asinf(quat[channel]);
752 float mat[4][4],
int auto_order,
int rotation_mode,
int channel,
bool angles,
float r_buf[4])
754 float *
const quat = r_buf;
755 float *
const eul = r_buf + 1;
777 float raw_quat[4], twist;
781 if (channel == axis + 1) {
791 quat[axis + 1] = twist;
814 {
"Object/Bone 1",
"Object/Bone 2"},
821 {
"Object/Bone 1",
"Object/Bone 2"},
859 if (dvar ==
nullptr) {
870 if (dtar->rna_path) {
898 if (dtar->rna_path) {
899 dtar->rna_path =
static_cast<char *
>(
MEM_dupallocN(dtar->rna_path));
911 if (
ELEM(
nullptr, dvar, dvti)) {
929 dtar->idtype =
ID_OB;
938 const char special_char_blacklist[] = {
939 '~',
'`',
'!',
'@',
'#',
'$',
'%',
'^',
'&',
'*',
'+',
'=',
'-',
'/',
'\\',
940 '?',
':',
';',
'<',
'>',
'{',
'}',
'[',
']',
'|',
' ',
'.',
'\t',
'\n',
'\r',
944 if (dvar ==
nullptr) {
952 if (dvar->
name[0] ==
'\0') {
962 else if (dvar->
name[0] ==
'_') {
969 if (strchr(dvar->
name,
' ')) {
972 if (strchr(dvar->
name,
'.')) {
977 for (
int i = 0;
i <
sizeof(special_char_blacklist);
i++) {
978 char *match = strchr(dvar->
name, special_char_blacklist[
i]);
980 if (match == dvar->
name) {
983 else if (match !=
nullptr) {
1015 if (driver ==
nullptr) {
1024 const char *name_default =
"var";
1078 if (driver ==
nullptr) {
1115 const char **names =
static_cast<const char **
>(
1122 names[
i++] = dvar->name;
1155 const char *message;
1159 if (isfinite(result_val)) {
1228 if (expression[0] ==
'\0') {
1232 if (strchr(expression,
'(') !=
nullptr) {
1236 if (strstr(expression,
"frame") !=
nullptr) {
1262 bool varname_changed)
1264 if (expr_changed || varname_changed) {
1274 if (varname_changed) {
1293 if (
ELEM(
nullptr, driver, dvar)) {
1337 driver->
curval = tot ? (value /
float(tot)) : 0.0f;
1359 value = std::max(tmp_val, value);
1363 value = std::min(tmp_val, value);
1394 std::scoped_lock
lock(python_driver_lock);
1414 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)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
ListBase BLI_listbase_from_link(Link *some_link)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void void void void void BLI_duplicatelist(ListBase *dst, const ListBase *src) ATTR_NONNULL(1
void void BLI_INLINE bool BLI_listbase_is_single(const ListBase *lb)
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 IN_RANGE_INCL(a, b, c)
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.
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)
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_callocN(size_t len, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(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)
const PointerRNA PointerRNA_NULL
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)
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
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]