== Python Button Evaluation ==

Users can write any valid Python expression (that evals to an int or float) inside Blender's gui number buttons (preceded by #) and have them evaluated to their actual int or float value.

Button Evaluation has access to the same modules as PyDrivers.

For example:

#1.0*9-2.3
#ob("Camera").LocZ
#1.0/ob("Cube").LocX
#math.sin(math.pi) -- or simply #m.sin(m.pi)
etc
This commit is contained in:
2006-06-12 00:10:00 +00:00
parent 7cad5ce842
commit 873e2eaae3
5 changed files with 88 additions and 4 deletions

View File

@@ -71,6 +71,8 @@ void BPY_free_screen_spacehandlers (struct bScreen *sc);
struct Object **BPY_pydriver_get_objects(struct IpoDriver *driver);
float BPY_pydriver_eval(struct IpoDriver *driver);
void BPY_pydriver_update(void);
/* button python evaluation */
int BPY_button_eval(char *expr, double *value);
/* writefile.c */
struct Oops;

View File

@@ -114,12 +114,15 @@ float BPY_pydriver_eval(struct IpoDriver *driver)
{
return 0;
}
/* depsgraph.c: */
struct Object **BPY_pydriver_get_objects(struct IpoDriver *driver)
{
return 0;
}
int BPY_button_eval(char *expr, double *value)
{
return 0;
}
/* writefile.c */
/* struct Oops; */

View File

@@ -85,6 +85,8 @@ extern "C" {
float BPY_pydriver_eval(struct IpoDriver *driver);
struct Object **BPY_pydriver_get_objects(struct IpoDriver *driver);
int BPY_button_eval(char *expr, double *value);
/* format importer hook */
int BPY_call_importloader( char *name );

View File

@@ -1144,6 +1144,74 @@ float BPY_pydriver_eval(IpoDriver *driver)
return result;
}
/* Button Python Evaluation */
/* Python evaluation for gui buttons:
* users can write any valid Python expression (that evals to an int or float)
* inside Blender's gui number buttons and have them evaluated to their
* actual int or float value.
*
* The global dict used for pydrivers is also used here, so all imported
* modules for pydrivers (including the pydrivers.py Blender text) are
* available for button py eval, too. */
static int bpy_button_eval_error(char *expr) {
if (bpy_pydriver_oblist)
bpy_pydriver_freeList();
if (bpy_pydriver_Dict) { /* free the persistent global dict */
/* it's the same dict used by pydrivers */
PyDict_Clear(bpy_pydriver_Dict);
Py_DECREF(bpy_pydriver_Dict);
bpy_pydriver_Dict = NULL;
}
fprintf(stderr, "\nError in button evaluation:\nThis is the failed Python expression:\n'%s'\n\n", expr);
PyErr_Print();
return -1;
}
int BPY_button_eval(char *expr, double *value)
{
PyObject *retval, *floatval;
if (!value || !expr || expr[0]=='\0') return -1;
*value = 0.0; /* default value */
if (!bpy_pydriver_Dict) {
if (bpy_pydriver_create_dict() != 0) {
fprintf(stderr,
"Button Python Eval error: couldn't create Python dictionary");
return -1;
}
}
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
bpy_pydriver_Dict);
if (retval == NULL) {
return bpy_button_eval_error(expr);
}
else {
floatval = PyNumber_Float(retval);
Py_DECREF(retval);
}
if (floatval == NULL)
return bpy_button_eval_error(expr);
else {
*value = (float)PyFloat_AsDouble(floatval);
Py_DECREF(floatval);
}
return 0; /* successful exit */
}
/*****************************************************************************/
/* ScriptLinks */
/*****************************************************************************/

View File

@@ -99,6 +99,8 @@
#include "BSE_view.h"
#include "BPY_extern.h" /* for BPY_button_eval */
#include "mydevice.h"
#include "interface.h"
#include "blendef.h"
@@ -2007,7 +2009,7 @@ static int ui_act_as_text_but(uiBut *but)
min= but->min;
max= but->max;
but->min= 0.0;
but->max= 15.0;
but->max= UI_MAX_DRAW_STR - 1; /* for py strings evaluation */
temp= but->type;
but->type= TEX;
textleft= but->flag & UI_TEXT_LEFT;
@@ -2024,8 +2026,15 @@ static int ui_act_as_text_but(uiBut *but)
but->max= max;
if(textleft==0) but->flag &= ~UI_TEXT_LEFT;
if( but->pointype==FLO ) value= atof(str);
else value= atoi(str);
if(str[0] == '#') {
if(BPY_button_eval(str+1, &value)) { /* str+1 to skip the # sign */
error("Invalid Python expression, check console");
retval = 0; /* invalidate return value if eval failed */
}
}
else value = atof(str);
if(but->pointype!=FLO) value= (int)value;
if(value<min) value= min;
if(value>max) value= max;