Blender V4.3
bpy_driver.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
13#include <Python.h>
14
15#include "DNA_anim_types.h"
16
17#include "BLI_listbase.h"
18#include "BLI_math_base.h"
19#include "BLI_string.h"
20
21#include "BKE_animsys.h"
22#include "BKE_fcurve_driver.h"
23#include "BKE_global.hh"
24#include "BKE_idtype.hh"
25
26#include "RNA_access.hh"
27#include "RNA_prototypes.hh"
28
29#include "bpy_rna_driver.hh" /* For #pyrna_driver_get_variable_value. */
30
31#include "bpy_intern_string.hh"
32
33#include "bpy_driver.hh"
34#include "bpy_rna.hh"
35
36#include "BPY_extern.hh"
37
38#define USE_RNA_AS_PYOBJECT
39
40#define USE_BYTECODE_WHITELIST
41
42#ifdef USE_BYTECODE_WHITELIST
43# include <opcode.h>
44#endif
45
46PyObject *bpy_pydriver_Dict = nullptr;
47
48#ifdef USE_BYTECODE_WHITELIST
49static PyObject *bpy_pydriver_Dict__whitelist = nullptr;
50#endif
51
53{
54 PyObject *d, *mod;
55
56 /* Validate name-space for driver evaluation. */
58 return -1;
59 }
60
61 d = PyDict_New();
62 if (d == nullptr) {
63 return -1;
64 }
65
67
68 /* Import some modules: `builtins`, `bpy`, `math`, `mathutils.noise`. */
69 PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
70
71 mod = PyImport_ImportModule("math");
72 if (mod) {
73 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */
74 Py_DECREF(mod);
75 }
76#ifdef USE_BYTECODE_WHITELIST
77 PyObject *mod_math = mod;
78#endif
79
80 /* Add `bpy` to global name-space. */
81 mod = PyImport_ImportModuleLevel("bpy", nullptr, nullptr, nullptr, 0);
82 if (mod) {
83 PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
84 Py_DECREF(mod);
85 }
86
87 /* Add noise to global name-space. */
88 mod = PyImport_ImportModuleLevel("mathutils", nullptr, nullptr, nullptr, 0);
89 if (mod) {
90 PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(mod), "noise");
91 PyDict_SetItemString(bpy_pydriver_Dict, "noise", modsub);
92 Py_DECREF(mod);
93 }
94
95 /* Add math utility functions. */
96 mod = PyImport_ImportModuleLevel("bl_math", nullptr, nullptr, nullptr, 0);
97 if (mod) {
98 static const char *names[] = {"clamp", "lerp", "smoothstep", nullptr};
99
100 for (const char **pname = names; *pname; ++pname) {
101 PyObject *func = PyDict_GetItemString(PyModule_GetDict(mod), *pname);
102 PyDict_SetItemString(bpy_pydriver_Dict, *pname, func);
103 }
104
105 Py_DECREF(mod);
106 }
107
108#ifdef USE_BYTECODE_WHITELIST
109 /* Setup the whitelist. */
110 {
111 bpy_pydriver_Dict__whitelist = PyDict_New();
112 const char *whitelist[] = {
113 /* builtins (basic) */
114 "all",
115 "any",
116 "len",
117 /* builtins (numeric) */
118 "max",
119 "min",
120 "pow",
121 "round",
122 "sum",
123 /* types */
124 "bool",
125 "float",
126 "int",
127 /* bl_math */
128 "clamp",
129 "lerp",
130 "smoothstep",
131
132 nullptr,
133 };
134
135 for (int i = 0; whitelist[i]; i++) {
136 PyDict_SetItemString(bpy_pydriver_Dict__whitelist, whitelist[i], Py_None);
137 }
138
139 /* Add all of `math` functions. */
140 if (mod_math != nullptr) {
141 PyObject *mod_math_dict = PyModule_GetDict(mod_math);
142 PyObject *arg_key, *arg_value;
143 Py_ssize_t arg_pos = 0;
144 while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
145 const char *arg_str = PyUnicode_AsUTF8(arg_key);
146 if (arg_str[0] && arg_str[1] != '_') {
147 PyDict_SetItem(bpy_pydriver_Dict__whitelist, arg_key, Py_None);
148 }
149 }
150 }
151 }
152#endif /* USE_BYTECODE_WHITELIST */
153
154 return 0;
155}
156
161static struct {
163
164 /* Borrowed reference to the `self` in `bpy_pydriver_Dict`
165 * keep for as long as the same self is used. */
166 PyObject *self = nullptr;
169
171{
172 if (g_pydriver_state_prev.evaltime != evaltime) {
173 PyObject *item = PyFloat_FromDouble(evaltime);
174 PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_frame, item);
175 Py_DECREF(item);
176
178 }
179}
180
182{
183 if ((g_pydriver_state_prev.self == nullptr) ||
184 (pyrna_driver_is_equal_anim_rna(anim_rna, g_pydriver_state_prev.self) == false))
185 {
186 PyObject *item = pyrna_driver_self_from_anim_rna(anim_rna);
187 PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_self, item);
188 Py_DECREF(item);
189
190 g_pydriver_state_prev.self = item;
191 }
192}
193
195{
196 if (g_pydriver_state_prev.self) {
197 PyDict_DelItem(bpy_pydriver_Dict, bpy_intern_str_self);
198
199 g_pydriver_state_prev.self = nullptr;
200 }
201}
202
204{
205 PointerRNA depsgraph_ptr = RNA_pointer_create(nullptr, &RNA_Depsgraph, depsgraph);
206 return pyrna_struct_CreatePyObject(&depsgraph_ptr);
207}
208
214{
215 /* This should never happen, but it's probably better to have None in Python
216 * than a nullptr-wrapping Depsgraph Python struct. */
217 BLI_assert(depsgraph != nullptr);
218 if (UNLIKELY(depsgraph == nullptr)) {
219 PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_depsgraph, Py_None);
220 g_pydriver_state_prev.depsgraph = nullptr;
221 return;
222 }
223
224 if ((g_pydriver_state_prev.depsgraph == nullptr) ||
225 (depsgraph != g_pydriver_state_prev.depsgraph->ptr.data))
226 {
228 PyDict_SetItem(bpy_pydriver_Dict, bpy_intern_str_depsgraph, item);
229 Py_DECREF(item);
230
231 g_pydriver_state_prev.depsgraph = (BPy_StructRNA *)item;
232 }
233}
234
236{
237 if (bpy_pydriver_Dict) { /* Free the global dict used by python-drivers. */
238 PyDict_Clear(bpy_pydriver_Dict);
239 Py_DECREF(bpy_pydriver_Dict);
240 bpy_pydriver_Dict = nullptr;
241 }
242
243#ifdef USE_BYTECODE_WHITELIST
245 PyDict_Clear(bpy_pydriver_Dict__whitelist);
248 }
249#endif
250
252
253 /* Freed when clearing driver dictionary. */
254 g_pydriver_state_prev.self = nullptr;
255 g_pydriver_state_prev.depsgraph = nullptr;
256}
257
259{
260 PyGILState_STATE gilstate;
261 const bool use_gil = true; /* !PyC_IsInterpreterActive(); */
262
263 if (use_gil) {
264 gilstate = PyGILState_Ensure();
265 }
266
267 /* Currently exit/reset are practically the same besides the GIL check. */
269
270 if (use_gil) {
271 PyGILState_Release(gilstate);
272 }
273}
274
280static void pydriver_error(ChannelDriver *driver, const PathResolvedRNA *anim_rna)
281{
282 driver->flag |= DRIVER_FLAG_INVALID; /* Python expression failed. */
283
284 const char *null_str = "<null>";
285 const ID *id = anim_rna->ptr.owner_id;
286 fprintf(stderr,
287 "\n"
288 "Error in PyDriver: expression failed: %s\n"
289 "For target: (type=%s, name=\"%s\", property=%s, property_index=%d)\n"
290 "\n",
291 driver->expression,
292 id ? BKE_idtype_idcode_to_name(GS(id->name)) : null_str,
293 id ? id->name + 2 : null_str,
294 anim_rna->prop ? RNA_property_identifier(anim_rna->prop) : null_str,
295 anim_rna->prop_index);
296
297 // BPy_errors_to_report(nullptr); /* TODO: reports. */
298 PyErr_Print();
299 PyErr_Clear();
300}
301
302#ifdef USE_BYTECODE_WHITELIST
303
304static bool is_opcode_secure(const int opcode)
305{
306 /* TODO(@ideasman42): Handle intrinsic opcodes (`CALL_INTRINSIC_1` & `CALL_INTRINSIC_2`).
307 * For Python 3.12. */
308
309# define OK_OP(op) \
310 case op: \
311 return true;
312
313 switch (opcode) {
314 OK_OP(CACHE)
315 OK_OP(POP_TOP)
316 OK_OP(PUSH_NULL)
317 OK_OP(NOP)
318# if PY_VERSION_HEX < 0x030c0000
319 OK_OP(UNARY_POSITIVE)
320# endif
321 OK_OP(UNARY_NEGATIVE)
322 OK_OP(UNARY_NOT)
323 OK_OP(UNARY_INVERT)
324 OK_OP(BINARY_SUBSCR)
325 OK_OP(GET_LEN)
326# if PY_VERSION_HEX < 0x030c0000
327 OK_OP(LIST_TO_TUPLE)
328# endif
329 OK_OP(RETURN_VALUE)
330 OK_OP(SWAP)
331 OK_OP(BUILD_TUPLE)
332 OK_OP(BUILD_LIST)
333 OK_OP(BUILD_SET)
334 OK_OP(BUILD_MAP)
335 OK_OP(COMPARE_OP)
336 OK_OP(JUMP_FORWARD)
337# if PY_VERSION_HEX < 0x030c0000
338 OK_OP(JUMP_IF_FALSE_OR_POP)
339 OK_OP(JUMP_IF_TRUE_OR_POP)
340 OK_OP(POP_JUMP_FORWARD_IF_FALSE)
341 OK_OP(POP_JUMP_FORWARD_IF_TRUE)
342# endif
343 OK_OP(LOAD_GLOBAL)
344 OK_OP(IS_OP)
345 OK_OP(CONTAINS_OP)
346 OK_OP(BINARY_OP)
347 OK_OP(LOAD_FAST)
348 OK_OP(STORE_FAST)
349 OK_OP(DELETE_FAST)
350# if PY_VERSION_HEX < 0x030c0000
351 OK_OP(POP_JUMP_FORWARD_IF_NOT_NONE)
352 OK_OP(POP_JUMP_FORWARD_IF_NONE)
353# endif
354 OK_OP(BUILD_SLICE)
355 OK_OP(LOAD_DEREF)
356 OK_OP(STORE_DEREF)
357 OK_OP(RESUME)
358 OK_OP(LIST_EXTEND)
359 OK_OP(SET_UPDATE)
360/* NOTE(@ideasman42): Don't enable dict manipulation, unless we can prove there is not way it
361 * can be used to manipulate the name-space (potentially allowing malicious code). */
362# if 0
363 OK_OP(DICT_MERGE)
364 OK_OP(DICT_UPDATE)
365# endif
366
367# if PY_VERSION_HEX < 0x030c0000
368 OK_OP(POP_JUMP_BACKWARD_IF_NOT_NONE)
369 OK_OP(POP_JUMP_BACKWARD_IF_NONE)
370 OK_OP(POP_JUMP_BACKWARD_IF_FALSE)
371 OK_OP(POP_JUMP_BACKWARD_IF_TRUE)
372# endif
373
374 /* Special cases. */
375 OK_OP(LOAD_CONST) /* Ok because constants are accepted. */
376 OK_OP(LOAD_NAME) /* Ok, because `PyCodeObject.names` is checked. */
377 OK_OP(CALL) /* Ok, because we check its "name" before calling. */
378 OK_OP(KW_NAMES) /* Ok, because it's used for calling functions with keyword arguments. */
379
380# if PY_VERSION_HEX < 0x030c0000
381 OK_OP(PRECALL) /* Ok, because it's used for calling. */
382# endif
383 }
384
385# undef OK_OP
386 return false;
387}
388
389bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code,
390 PyObject *py_namespace_array[],
391 const bool verbose,
392 const char *error_prefix)
393{
394 PyCodeObject *py_code = (PyCodeObject *)expr_code;
395
396 /* Check names. */
397 {
398 for (int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
399 PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
400 const char *name_str = PyUnicode_AsUTF8(name);
401 bool contains_name = false;
402 for (int j = 0; py_namespace_array[j]; j++) {
403 if (PyDict_Contains(py_namespace_array[j], name)) {
404 contains_name = true;
405 break;
406 }
407 }
408
409 if ((contains_name == false) || (name_str[0] == '_')) {
410 if (verbose) {
411 fprintf(stderr,
412 "\t%s: restricted access disallows name '%s', "
413 "enable auto-execution to support\n",
414 error_prefix,
415 name_str);
416 }
417 return false;
418 }
419 }
420 }
421
422 /* Check opcodes. */
423 {
424 const _Py_CODEUNIT *codestr;
425 Py_ssize_t code_len;
426
427 PyObject *co_code;
428
429 co_code = PyCode_GetCode(py_code);
430 if (UNLIKELY(!co_code)) {
431 PyErr_Print();
432 PyErr_Clear();
433 return false;
434 }
435
436 PyBytes_AsStringAndSize(co_code, (char **)&codestr, &code_len);
437 code_len /= sizeof(*codestr);
438 bool ok = true;
439
440 /* Loop over op-code's, the op-code arguments are ignored. */
441 for (Py_ssize_t i = 0; i < code_len; i++) {
442 const int opcode = _Py_OPCODE(codestr[i]);
443 if (!is_opcode_secure(opcode)) {
444 if (verbose) {
445 fprintf(stderr,
446 "\t%s: restricted access disallows opcode '%d', "
447 "enable auto-execution to support\n",
448 error_prefix,
449 opcode);
450 }
451 ok = false;
452 break;
453 }
454 }
455
456 Py_DECREF(co_code);
457 if (!ok) {
458 return false;
459 }
460 }
461
462 return true;
463}
464
465bool BPY_driver_secure_bytecode_test(PyObject *expr_code,
466 PyObject *py_namespace,
467 const bool verbose)
468{
469
470 if (!bpy_pydriver_Dict) {
471 if (bpy_pydriver_create_dict() != 0) {
472 fprintf(stderr, "%s: couldn't create Python dictionary\n", __func__);
473 return false;
474 }
475 }
476 PyObject *py_namespaces[] = {
477 bpy_pydriver_Dict, bpy_pydriver_Dict__whitelist, py_namespace, nullptr};
478 return BPY_driver_secure_bytecode_test_ex(expr_code, py_namespaces, verbose, __func__);
479}
480
481#endif /* USE_BYTECODE_WHITELIST */
483 ChannelDriver *driver,
484 ChannelDriver *driver_orig,
485 const AnimationEvalContext *anim_eval_context)
486{
487 /* (old) NOTE: PyGILState_Ensure() isn't always called because python can call
488 * the bake operator which intern starts a thread which calls scene update
489 * which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive()
490 * if #PyGILState_Ensure() is needed, see #27683.
491 *
492 * (new) NOTE: checking if python is running is not thread-safe #28114
493 * now release the GIL on python operator execution instead, using
494 * #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender.
495 *
496 * For copy-on-evaluation we always cache expressions and write errors in the
497 * original driver, otherwise these would get freed while editing.
498 * Due to the GIL this is thread-safe. */
499
500 PyObject *driver_vars = nullptr;
501 PyObject *retval = nullptr;
502
503 /* Speed up by pre-hashing string & avoids re-converting unicode strings for every execution. */
504 PyObject *expr_vars;
505
506 PyObject *expr_code;
507 PyGILState_STATE gilstate;
508 bool use_gil;
509
510 DriverVar *dvar;
511 double result = 0.0; /* Default return. */
512 const char *expr;
513 bool targets_ok = true;
514 int i;
515
516 /* Get the python expression to be evaluated. */
517 expr = driver_orig->expression;
518 if (expr[0] == '\0') {
519 return 0.0f;
520 }
521
522#ifndef USE_BYTECODE_WHITELIST
523 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
526 SNPRINTF(G.autoexec_fail, "Driver '%s'", expr);
527
528 printf("skipping driver '%s', automatic scripts are disabled\n", expr);
529 }
530 driver_orig->flag |= DRIVER_FLAG_PYTHON_BLOCKED;
531 return 0.0f;
532 }
533#else
534 bool is_recompile = false;
535#endif
536
537 use_gil = true; /* !PyC_IsInterpreterActive(); */
538
539 if (use_gil) {
540 gilstate = PyGILState_Ensure();
541 }
542
543 /* Needed since drivers are updated directly after undo where `main` is re-allocated #28807. */
545
546 /* Initialize global dictionary for Python driver evaluation settings. */
547 if (!bpy_pydriver_Dict) {
548 if (bpy_pydriver_create_dict() != 0) {
549 fprintf(stderr, "%s: couldn't create Python dictionary\n", __func__);
550 if (use_gil) {
551 PyGILState_Release(gilstate);
552 }
553 return 0.0f;
554 }
555 }
556
557 /* Update global name-space. */
559
560 if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
562 }
563 else {
565 }
566
568
569 if (driver_orig->expr_comp == nullptr) {
570 driver_orig->flag |= DRIVER_FLAG_RECOMPILE;
571 }
572
573 /* Compile the expression first if it hasn't been compiled or needs to be rebuilt. */
574 if (driver_orig->flag & DRIVER_FLAG_RECOMPILE) {
575 Py_XDECREF(driver_orig->expr_comp);
576 driver_orig->expr_comp = PyTuple_New(2);
577
578 expr_code = Py_CompileString(expr, "<bpy driver>", Py_eval_input);
579 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, expr_code);
580
581 driver_orig->flag &= ~DRIVER_FLAG_RECOMPILE;
582
583 /* Maybe this can be removed but for now best keep until were sure. */
584 driver_orig->flag |= DRIVER_FLAG_RENAMEVAR;
585 driver_orig->flag &= ~DRIVER_FLAG_PYTHON_BLOCKED;
586
587#ifdef USE_BYTECODE_WHITELIST
588 is_recompile = true;
589#endif
590 }
591 else {
592 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 0);
593 }
594
595 if (driver_orig->flag & DRIVER_FLAG_RENAMEVAR) {
596 /* May not be set. */
597 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
598 Py_XDECREF(expr_vars);
599
600 expr_vars = PyTuple_New(BLI_listbase_count(&driver_orig->variables));
601 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 1, expr_vars);
602
603 for (dvar = static_cast<DriverVar *>(driver_orig->variables.first), i = 0; dvar;
604 dvar = dvar->next)
605 {
606 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
607 }
608
609 driver_orig->flag &= ~DRIVER_FLAG_RENAMEVAR;
610 }
611 else {
612 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->expr_comp), 1);
613 }
614
615 /* Add target values to a dict that will be used as `__locals__` dict. */
616 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
617 for (dvar = static_cast<DriverVar *>(driver->variables.first), i = 0; dvar; dvar = dvar->next) {
618 PyObject *driver_arg = nullptr;
619
620/* Support for any RNA data. */
621#ifdef USE_RNA_AS_PYOBJECT
622 if (dvar->type == DVAR_TYPE_SINGLE_PROP) {
624 anim_eval_context, driver, dvar, &dvar->targets[0]);
625
626 if (driver_arg == nullptr) {
627 driver_arg = PyFloat_FromDouble(0.0);
628 dvar->curval = 0.0f;
629 }
630 else {
631 /* No need to worry about overflow here, values from RNA are within limits. */
632 if (PyFloat_CheckExact(driver_arg)) {
633 dvar->curval = float(PyFloat_AsDouble(driver_arg));
634 }
635 else if (PyLong_CheckExact(driver_arg)) {
636 dvar->curval = float(PyLong_AsLong(driver_arg));
637 }
638 else if (PyBool_Check(driver_arg)) {
639 dvar->curval = float(driver_arg == Py_True);
640 }
641 else {
642 dvar->curval = 0.0f;
643 }
644 }
645 }
646 else
647#endif
648 {
649 /* Try to get variable value. */
650 const float tval = driver_get_variable_value(anim_eval_context, driver, dvar);
651 driver_arg = PyFloat_FromDouble(double(tval));
652 }
653
654 /* Try to add to dictionary. */
655 /* `if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) {` */
656 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
657 /* Pass. */
658 }
659 else {
660 /* This target failed - bad name. */
661 if (targets_ok) {
662 /* First one, print some extra info for easier identification. */
663 fprintf(stderr, "\n%s: Error while evaluating PyDriver:\n", __func__);
664 targets_ok = false;
665 }
666
667 fprintf(stderr, "\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->name);
668 // BPy_errors_to_report(nullptr); /* TODO: reports. */
669 PyErr_Print();
670 PyErr_Clear();
671 }
672 Py_DECREF(driver_arg);
673 }
674
675#ifdef USE_BYTECODE_WHITELIST
676 if (is_recompile && expr_code) {
677 if (!(G.f & G_FLAG_SCRIPT_AUTOEXEC)) {
678 PyObject *py_namespaces[] = {
679 bpy_pydriver_Dict, bpy_pydriver_Dict__whitelist, driver_vars, nullptr};
681 expr_code,
682 py_namespaces,
683 /* Always be verbose since this can give hints to why evaluation fails. */
684 true,
685 __func__))
686 {
689 SNPRINTF(G.autoexec_fail, "Driver '%s'", expr);
690 }
691
692 Py_DECREF(expr_code);
693 expr_code = nullptr;
694 PyTuple_SET_ITEM(((PyObject *)driver_orig->expr_comp), 0, nullptr);
695 driver_orig->flag |= DRIVER_FLAG_PYTHON_BLOCKED;
696 }
697 }
698 }
699#endif /* USE_BYTECODE_WHITELIST */
700
701#if 0 /* slow, with this can avoid all Py_CompileString above. */
702 /* execute expression to get a value */
703 retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
704#else
705 /* Evaluate the compiled expression. */
706 if (expr_code) {
707 retval = PyEval_EvalCode(
708 static_cast<PyObject *>((void *)expr_code), bpy_pydriver_Dict, driver_vars);
709 }
710#endif
711
712 /* Decref the driver variables first. */
713 Py_DECREF(driver_vars);
714
715 /* Process the result. */
716 if (retval == nullptr) {
717 pydriver_error(driver, anim_rna);
718 }
719 else {
720 if (UNLIKELY((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
721 pydriver_error(driver, anim_rna);
722 result = 0.0;
723 }
724 else {
725 /* All fine, make sure the "invalid expression" flag is cleared. */
726 driver->flag &= ~DRIVER_FLAG_INVALID;
727 }
728 Py_DECREF(retval);
729 }
730
731 if (use_gil) {
732 PyGILState_Release(gilstate);
733 }
734
735 if (UNLIKELY(!isfinite(result))) {
736 fprintf(stderr, "\t%s: driver '%s' evaluates to '%f'\n", __func__, driver->expression, result);
737 return 0.0f;
738 }
739
740 return float(result);
741}
float driver_get_variable_value(const struct AnimationEvalContext *anim_eval_context, struct ChannelDriver *driver, struct DriverVar *dvar)
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL
@ G_FLAG_SCRIPT_AUTOEXEC
const char * BKE_idtype_idcode_to_name(short idcode)
Definition idtype.cc:168
#define BLI_assert(a)
Definition BLI_assert.h:50
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
#define SWAP(type, a, b)
#define UNLIKELY(x)
@ DVAR_TYPE_SINGLE_PROP
@ DRIVER_FLAG_INVALID
@ DRIVER_FLAG_PYTHON_BLOCKED
@ DRIVER_FLAG_RECOMPILE
@ DRIVER_FLAG_USE_SELF
@ DRIVER_FLAG_RENAMEVAR
#define arg_str(...)
Definition bgl.cc:412
static PyObject * bpy_pydriver_Dict__whitelist
Definition bpy_driver.cc:49
static bool is_opcode_secure(const int opcode)
PyObject * bpy_pydriver_Dict
Definition bpy_driver.cc:46
static void bpy_pydriver_namespace_update_depsgraph(Depsgraph *depsgraph)
PyObject * self
static void pydriver_error(ChannelDriver *driver, const PathResolvedRNA *anim_rna)
static void bpy_pydriver_namespace_update_self(PathResolvedRNA *anim_rna)
float BPY_driver_exec(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context)
float evaltime
BPy_StructRNA * depsgraph
static void bpy_pydriver_namespace_update_frame(const float evaltime)
#define OK_OP(op)
static struct @1344 g_pydriver_state_prev
int bpy_pydriver_create_dict()
Definition bpy_driver.cc:52
bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code, PyObject *py_namespace_array[], const bool verbose, const char *error_prefix)
static PyObject * bpy_pydriver_depsgraph_as_pyobject(Depsgraph *depsgraph)
void BPY_driver_reset()
static void bpy_pydriver_namespace_clear_self()
void BPY_driver_exit()
bool BPY_driver_secure_bytecode_test(PyObject *expr_code, PyObject *py_namespace, const bool verbose)
PyObject * bpy_intern_str_depsgraph
PyObject * bpy_intern_str_self
PyObject * bpy_intern_str_frame
void BPY_update_rna_module()
Definition bpy_rna.cc:7916
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:7694
PyObject * pyrna_driver_get_variable_value(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar, DriverTarget *dtar)
PyObject * pyrna_driver_self_from_anim_rna(PathResolvedRNA *anim_rna)
bool pyrna_driver_is_equal_anim_rna(const PathResolvedRNA *anim_rna, const PyObject *py_anim_rna)
static int verbose
Definition cineonlib.cc:31
#define printf
draw_view in_light_buf[] float
#define GS(x)
Definition iris.cc:202
#define G(x, y, z)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
const char * RNA_property_identifier(const PropertyRNA *prop)
#define CALL(member, value_str)
#define FLT_MAX
Definition stdcycles.h:14
struct Depsgraph * depsgraph
Definition BKE_animsys.h:41
PyObject_HEAD PointerRNA ptr
Definition bpy_rna.hh:124
char expression[256]
struct DriverVar * next
DriverTarget targets[8]
char name[64]
Definition DNA_ID.h:413
void * first
PointerRNA ptr
Definition RNA_types.hh:56
PropertyRNA * prop
Definition RNA_types.hh:57
ID * owner_id
Definition RNA_types.hh:40
void * data
Definition RNA_types.hh:42
ccl_device_inline int mod(int x, int m)
Definition util/math.h:520