adding back button evaluation so you can do 1/60, 90*0.1 etc as well as dimension...
authorCampbell Barton <ideasman42@gmail.com>
Mon, 10 Aug 2009 11:58:53 +0000 (11:58 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 10 Aug 2009 11:58:53 +0000 (11:58 +0000)
Note...
- Python3.1 you don't need to add the .0 for divisions anymore (was esp annoying for button eval)
- Simple dimension input, imperial mi/yd/ft/in, metric km/m/cm/mm,  Later could display these values and have a pref for scene scale, atm it assumes 1BU == 1m.

release/ui/bpy_ops.py
source/blender/editors/interface/SConscript
source/blender/editors/interface/interface.c
source/blender/python/BPY_extern.h
source/blender/python/intern/bpy_interface.c

index aa9bfb460f0b5f0b86c1e94f050ab69daea87916..1d79f1a331f978186fef2ff849e50ed8d62e057c 100644 (file)
@@ -111,3 +111,48 @@ class bpy_ops_submodule_op(object):
 
 import bpy
 bpy.ops = bpy_ops()
+
+
+
+
+# A bit out of place but add button conversion code here
+module_type = type(__builtins__)
+import types
+mod = types.ModuleType('button_convert')
+
+import sys
+sys.modules['button_convert'] = mod
+
+def convert(expr):
+       
+       def replace(string, unit, scaler):
+               # in need of regex
+               change = True
+               while change:
+                       change = False
+                       i = string.find(unit)
+                       if i != -1:
+                               if i>0 and not string[i-1].isalpha():
+                                       i_end = i+len(unit)
+                                       if i_end+1 >= len(string) or (not string[i_end+1].isalpha()):
+                                               string = string.replace(unit, scaler)
+                                               change = True
+               # print(string)
+               return string
+       
+       #imperial
+       expr = replace(expr, 'mi', '*1609.344')
+       expr = replace(expr, 'yd', '*0.9144')
+       expr = replace(expr, 'ft', '*0.3048')
+       expr = replace(expr, 'in', '*0.0254')
+       
+       # metric
+       expr = replace(expr, 'km', '*1000')
+       expr = replace(expr, 'm', '')
+       expr = replace(expr, 'cm', '*0.01')
+       expr = replace(expr, 'mm', '*0.001')
+       
+       return expr
+
+mod.convert = convert
+
index bac3742c12feed313f42094177afddaede8026ef..e44de5410f16696613630c6951987da2d3e40047 100644 (file)
@@ -9,6 +9,7 @@ for source in env.Glob('*_api.c'):
 incs = '../include ../../blenlib ../../blenfont ../../blenkernel ../../makesdna ../../imbuf'
 incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc'
 incs += ' #/extern/glew/include'
+incs += ' ../../python/' # python button eval
 
 defs = []
 
index 9e9b6165a73870b08764fe32d2a70c092385c4b8..f3bb975a1f7225065986f9710450331616b19ea5 100644 (file)
@@ -66,6 +66,8 @@
 #include "RNA_access.h"
 #include "RNA_types.h"
 
+#include "BPY_extern.h"
+
 #include "interface_intern.h"
 
 #define MENU_WIDTH                     120
@@ -1434,10 +1436,9 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
                double value;
 
                /* XXX 2.50 missing python api */
-#if 0
-               if(BPY_button_eval(str, &value)) {
-                       BKE_report(CTX_reports(C), RPT_WARNING, "Invalid Python expression, check console");
-                       value = 0.0f; /* Zero out value on error */
+#ifndef DISABLE_PYTHON
+               if(BPY_button_eval(C, str, &value)) {
+                       value = ui_get_but_val(but); /* use its original value */
                        
                        if(str[0])
                                return 0;
index db0404c33a8ee1744a41ae94ed80d0b41c501583..acb45790ed2234f20b3b6578f353b6f51b347b66 100644 (file)
@@ -122,7 +122,7 @@ extern "C" {
        void BPY_pydriver_update(void);
        float BPY_pydriver_eval(struct ChannelDriver *driver);
 
-       int BPY_button_eval(char *expr, double *value);
+       int BPY_button_eval(struct bContext *C, char *expr, double *value);
 
 /* format importer hook */
        int BPY_call_importloader( char *name );
index e37e75ab80d3293b8dac0e078d9f12a33fef4d0b..8cd4cdd5dfc739304cdddd64fc67b8631fbfbb4a 100644 (file)
@@ -804,3 +804,65 @@ float BPY_pydriver_eval (ChannelDriver *driver)
 
        return result;
 }
+
+int BPY_button_eval(bContext *C, char *expr, double *value)
+{
+       PyGILState_STATE gilstate;
+       PyObject *dict, *retval, *expr_conv;
+       int error_ret = 0;
+       
+       if (!value || !expr || expr[0]=='\0') return -1;
+       
+       bpy_context_set(C, &gilstate);
+       
+       // experemental, fun. "button_convert.convert" is currently defined in bpy_ops.py
+       {
+               PyObject *mod= PyDict_GetItemString(PySys_GetObject("modules"), "button_convert");
+               if(mod && PyModule_Check(mod))  {
+                       PyObject *mod_dict= PyModule_GetDict(mod);
+                       PyObject *func= PyDict_GetItemString(mod_dict, "convert");
+                       if(func) {
+                               PyObject *expr_conv = PyObject_CallFunction(func, "s", expr);
+                               if(expr_conv==NULL) {
+                                       PyErr_Print();
+                                       PyErr_Clear();
+                               }
+                               else {
+                                       expr= _PyUnicode_AsString(expr_conv); /* TODO, check */
+                               }
+                       }
+               }
+       }
+       
+       dict= CreateGlobalDictionary(C);
+       retval = PyRun_String(expr, Py_eval_input, dict, dict);
+       
+       if(expr_conv) {
+               Py_DECREF(expr_conv); /* invalidates expr */
+       }
+       
+       if (retval == NULL) {
+               error_ret= -1;
+       }
+       else {
+               double val = PyFloat_AsDouble(retval);
+               Py_DECREF(retval);
+               
+               if(val==-1 && PyErr_Occurred()) {
+                       error_ret= -1;
+               }
+               else {
+                       *value= val;
+               }
+       }
+       
+       if(error_ret) {
+               BPy_errors_to_report(CTX_wm_reports(C));
+       }
+       
+       Py_DECREF(dict);
+       bpy_context_clear(C, &gilstate);
+       
+       return error_ret;
+}
+