renamed bpy.sys to bpy.utils, since it used to be a attempt to replace pythons sys...
[blender.git] / source / blender / python / intern / bpy_interface.c
index 3e28bc7968f931a40ba56efa013aa9aa84d8a10b..b465a494a4d88013d9b7e641420e1998bc8c5186 100644 (file)
@@ -63,6 +63,7 @@
 #include "BKE_context.h"
 #include "BKE_fcurve.h"
 #include "BKE_text.h"
+#include "BKE_context.h"
 
 #include "BPY_extern.h"
 
@@ -147,6 +148,17 @@ void bpy_context_clear(bContext *C, PyGILState_STATE *gilstate)
        }
 }
 
+static void bpy_import_test(char *modname)
+{
+       PyObject *mod= PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
+       if(mod) {
+               Py_DECREF(mod);
+       }
+       else {
+               PyErr_Print();
+               PyErr_Clear();
+       }       
+}
 
 void BPY_free_compiled_text( struct Text *text )
 {
@@ -176,7 +188,22 @@ static void bpy_init_modules( void )
        PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
        Py_DECREF(mod);
 
-
+       /* add our own modules dir */
+       {
+               char *modpath= BLI_gethome_folder("scripts/modules", BLI_GETHOME_ALL);
+               
+               if(modpath) {
+                       PyObject *sys_path= PySys_GetObject("path"); /* borrow */
+                       PyObject *py_modpath= PyUnicode_FromString(modpath);
+                       PyList_Insert(sys_path, 0, py_modpath); /* add first */
+                       Py_DECREF(py_modpath);
+               }
+               
+               bpy_import_test("bpy_ops"); /* adds its self to bpy.ops */
+               bpy_import_test("bpy_utils"); /* adds its self to bpy.sys */
+               bpy_import_test("bpy_ext"); /* extensions to our existing types */
+       }
+       
        /* stand alone utility modules not related to blender directly */
        Geometry_Init();
        Mathutils_Init();
@@ -216,6 +243,9 @@ static PyObject *CreateGlobalDictionary( bContext *C )
                        {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
                        {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
                        {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
+                       {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""},
+                       {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""},
+                       {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""},
                        {NULL, NULL, 0, NULL}
                };
                
@@ -577,7 +607,7 @@ void BPY_run_ui_scripts(bContext *C, int reload)
        char *file_extension;
        char *dirname;
        char path[FILE_MAX];
-       char *dirs[] = {"ui", "io", NULL};
+       char *dirs[] = {"scripts/ui", "scripts/io", NULL};
        int path_flags[] = {BLI_GETHOME_LOCAL|BLI_GETHOME_SYSTEM, BLI_GETHOME_USER}; /* SYSTEM / NON-SYSTEM */
        int a, err, flag_iter;
        
@@ -856,7 +886,7 @@ float BPY_pydriver_eval (ChannelDriver *driver)
 int BPY_button_eval(bContext *C, char *expr, double *value)
 {
        PyGILState_STATE gilstate;
-       PyObject *dict, *retval;
+       PyObject *dict, *mod, *retval;
        int error_ret = 0;
        
        if (!value || !expr || expr[0]=='\0') return -1;
@@ -864,6 +894,20 @@ int BPY_button_eval(bContext *C, char *expr, double *value)
        bpy_context_set(C, &gilstate);
        
        dict= CreateGlobalDictionary(C);
+       
+       /* import some modules: builtins,math*/
+       PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
+
+       mod = PyImport_ImportModule("math");
+       if (mod) {
+               PyDict_Merge(dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
+               
+               /* Only keep for backwards compat! - just import all math into root, they are standard */
+               PyDict_SetItemString(dict, "math", mod);
+               PyDict_SetItemString(dict, "m", mod);
+               Py_DECREF(mod);
+       } 
+       
        retval = PyRun_String(expr, Py_eval_input, dict, dict);
        
        if (retval == NULL) {
@@ -905,3 +949,65 @@ int BPY_button_eval(bContext *C, char *expr, double *value)
        return error_ret;
 }
 
+
+
+int bpy_context_get(bContext *C, const char *member, bContextDataResult *result)
+{
+       PyObject *pyctx= (PyObject *)CTX_py_dict_get(C);
+       PyObject *item= PyDict_GetItemString(pyctx, member);
+       PointerRNA *ptr= NULL;
+       int done= 0;
+
+       if(item==NULL) {
+               /* pass */
+       }
+       else if(item==Py_None) {
+               /* pass */
+       }
+       else if(BPy_StructRNA_Check(item)) {
+               ptr= &(((BPy_StructRNA *)item)->ptr);
+
+               //result->ptr= ((BPy_StructRNA *)item)->ptr;
+               CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data);
+               done= 1;
+       }
+       else if (PySequence_Check(item)) {
+               PyObject *seq_fast= PySequence_Fast(item, "bpy_context_get sequence conversion");
+               if (seq_fast==NULL) {
+                       PyErr_Print();
+                       PyErr_Clear();
+               }
+               else {
+                       int len= PySequence_Fast_GET_SIZE(seq_fast);
+                       int i;
+                       for(i = 0; i < len; i++) {
+                               PyObject *list_item= PySequence_Fast_GET_ITEM(seq_fast, i);
+
+                               if(BPy_StructRNA_Check(list_item)) {
+                                       /*
+                                       CollectionPointerLink *link= MEM_callocN(sizeof(CollectionPointerLink), "bpy_context_get");
+                                       link->ptr= ((BPy_StructRNA *)item)->ptr;
+                                       BLI_addtail(&result->list, link);
+                                       */
+                                       ptr= &(((BPy_StructRNA *)list_item)->ptr);
+                                       CTX_data_list_add(result, ptr->id.data, ptr->type, ptr->data);
+                               }
+                               else {
+                                       printf("List item not a valid type\n");
+                               }
+
+                       }
+                       Py_DECREF(seq_fast);
+
+                       done= 1;
+               }
+       }
+
+       if(done==0) {
+               if (item)       printf("Context '%s' not found\n", member);
+               else            printf("Context '%s' not a valid type\n", member);
+       }
+
+       return done;
+}
+