OBJ exporter working (Python 3.0), but needs testing and fixing.
[blender.git] / source / blender / python / intern / bpy_interface.c
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6
7 #ifndef WIN32
8 #include <dirent.h>
9 #else
10 #include "BLI_winstuff.h"
11 #endif
12
13 #include <Python.h>
14 #include "compile.h"            /* for the PyCodeObject */
15 #include "eval.h"               /* for PyEval_EvalCode */
16
17 #include "bpy_compat.h"
18
19 #include "bpy_rna.h"
20 #include "bpy_operator.h"
21 #include "bpy_ui.h"
22 #include "bpy_sys.h"
23 #include "bpy_util.h"
24
25 #include "DNA_anim_types.h"
26 #include "DNA_space_types.h"
27 #include "DNA_text_types.h"
28
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_util.h"
32 #include "BLI_string.h"
33
34 #include "BKE_context.h"
35 #include "BKE_fcurve.h"
36 #include "BKE_text.h"
37
38 #include "BPY_extern.h"
39
40 #include "../generic/bpy_internal_import.h" // our own imports
41 /* external util modukes */
42
43 #include "../generic/Mathutils.h"
44 #include "../generic/Geometry.h"
45 #include "../generic/BGL.h"
46
47
48 void BPY_free_compiled_text( struct Text *text )
49 {
50         if( text->compiled ) {
51                 Py_DECREF( ( PyObject * ) text->compiled );
52                 text->compiled = NULL;
53         }
54 }
55
56 /*****************************************************************************
57 * Description: Creates the bpy module and adds it to sys.modules for importing
58 *****************************************************************************/
59 static void bpy_init_modules( void )
60 {
61         PyObject *mod;
62         
63         mod = PyModule_New("bpy");
64         
65         PyModule_AddObject( mod, "data", BPY_rna_module() );
66         /* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
67         PyModule_AddObject( mod, "types", BPY_rna_types() );
68         PyModule_AddObject( mod, "props", BPY_rna_props() );
69         PyModule_AddObject( mod, "ops", BPY_operator_module() );
70         PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experimental, consider this a test, especially PyCObject is not meant to be permanent
71         
72         /* add the module so we can import it */
73         PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
74         Py_DECREF(mod);
75
76
77         /* stand alone utility modules not related to blender directly */
78         Geometry_Init("Geometry");
79         Mathutils_Init("Mathutils");
80         BGL_Init("BGL");
81 }
82
83 #if (PY_VERSION_HEX < 0x02050000)
84 PyObject *PyImport_ImportModuleLevel(char *name, void *a, void *b, void *c, int d)
85 {
86         return PyImport_ImportModule(name);
87 }
88 #endif
89
90 void BPY_update_modules( void )
91 {
92         PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
93         PyModule_AddObject( mod, "data", BPY_rna_module() );
94         PyModule_AddObject( mod, "types", BPY_rna_types() );
95         PyModule_AddObject( mod, "sys", BPY_sys_module() );
96 }
97
98 /*****************************************************************************
99 * Description: This function creates a new Python dictionary object.
100 *****************************************************************************/
101 static PyObject *CreateGlobalDictionary( bContext *C )
102 {
103         PyObject *mod;
104         PyObject *dict = PyDict_New(  );
105         PyObject *item = PyUnicode_FromString( "__main__" );
106         PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
107         PyDict_SetItemString( dict, "__name__", item );
108         Py_DECREF(item);
109         
110         // XXX - evil, need to access context
111         BPy_SetContext(C);
112         
113         // XXX - put somewhere more logical
114         {
115                 PyMethodDef *ml;
116                 static PyMethodDef bpy_prop_meths[] = {
117                         {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
118                         {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
119                         {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
120                         {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
121                         {NULL, NULL, 0, NULL}
122                 };
123                 
124                 for(ml = bpy_prop_meths; ml->ml_name; ml++) {
125                         PyDict_SetItemString( dict, ml->ml_name, PyCFunction_New(ml, NULL));
126                 }
127         }
128         
129         /* add bpy to global namespace */
130         mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
131         PyDict_SetItemString( dict, "bpy", mod );
132         Py_DECREF(mod);
133         
134         return dict;
135 }
136
137 void BPY_start_python( int argc, char **argv )
138 {
139         PyThreadState *py_tstate = NULL;
140         
141         Py_Initialize(  );
142         
143         //PySys_SetArgv( argc_copy, argv_copy );
144         
145         /* Initialize thread support (also acquires lock) */
146         PyEval_InitThreads();
147         
148         
149         /* bpy.* and lets us import it */
150         bpy_init_modules(); 
151
152         { /* our own import and reload functions */
153                 PyObject *item;
154                 //PyObject *m = PyImport_AddModule("__builtin__");
155                 //PyObject *d = PyModule_GetDict(m);
156                 PyObject *d = PyEval_GetBuiltins(  );
157                 PyDict_SetItemString(d, "reload",               item=PyCFunction_New(bpy_reload_meth, NULL));   Py_DECREF(item);
158                 PyDict_SetItemString(d, "__import__",   item=PyCFunction_New(bpy_import_meth, NULL));   Py_DECREF(item);
159         }
160         
161         py_tstate = PyGILState_GetThisThreadState();
162         PyEval_ReleaseThread(py_tstate);
163 }
164
165 void BPY_end_python( void )
166 {
167         PyGILState_Ensure(); /* finalizing, no need to grab the state */
168         
169         // free other python data.
170         //BPY_rna_free_types();
171         
172         Py_Finalize(  );
173         
174         return;
175 }
176
177 /* Can run a file or text block */
178 int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
179 {
180         PyObject *py_dict, *py_result;
181         PyGILState_STATE gilstate;
182         
183         if (fn==NULL && text==NULL) {
184                 return 0;
185         }
186         
187         //BPY_start_python();
188         
189         gilstate = PyGILState_Ensure();
190
191         BPY_update_modules(); /* can give really bad results if this isnt here */
192         bpy_import_main_set(CTX_data_main(C));
193         
194         py_dict = CreateGlobalDictionary(C);
195
196         if (text) {
197                 
198                 if( !text->compiled ) { /* if it wasn't already compiled, do it now */
199                         char *buf = txt_to_buf( text );
200
201                         text->compiled =
202                                 Py_CompileString( buf, text->id.name+2, Py_file_input );
203
204                         MEM_freeN( buf );
205
206                         if( PyErr_Occurred(  ) ) {
207                                 BPy_errors_to_report(reports);
208                                 BPY_free_compiled_text( text );
209                                 PyGILState_Release(gilstate);
210                                 return 0;
211                         }
212                 }
213                 py_result =  PyEval_EvalCode( text->compiled, py_dict, py_dict );
214                 
215         } else {
216                 char pystring[512];
217                 /* TODO - look into a better way to run a file */
218                 sprintf(pystring, "exec(open(r'%s').read())", fn);      
219                 py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );                  
220         }
221         
222         if (!py_result) {
223                 BPy_errors_to_report(reports);
224         } else {
225                 Py_DECREF( py_result );
226         }
227         
228         Py_DECREF(py_dict);
229         PyGILState_Release(gilstate);
230         bpy_import_main_set(NULL);
231         
232         //BPY_end_python();
233         return py_result ? 1:0;
234 }
235
236
237 /* TODO - move into bpy_space.c ? */
238 /* GUI interface routines */
239
240 /* Copied from Draw.c */
241 static void exit_pydraw( SpaceScript * sc, short err )
242 {
243         Script *script = NULL;
244
245         if( !sc || !sc->script )
246                 return;
247
248         script = sc->script;
249
250         if( err ) {
251                 BPy_errors_to_report(NULL); // TODO, reports
252                 script->flags = 0;      /* mark script struct for deletion */
253                 SCRIPT_SET_NULL(script);
254                 script->scriptname[0] = '\0';
255                 script->scriptarg[0] = '\0';
256 // XXX 2.5              error_pyscript();
257 // XXX 2.5              scrarea_queue_redraw( sc->area );
258         }
259
260 #if 0 // XXX 2.5
261         BPy_Set_DrawButtonsList(sc->but_refs);
262         BPy_Free_DrawButtonsList(); /*clear all temp button references*/
263 #endif
264
265         sc->but_refs = NULL;
266         
267         Py_XDECREF( ( PyObject * ) script->py_draw );
268         Py_XDECREF( ( PyObject * ) script->py_event );
269         Py_XDECREF( ( PyObject * ) script->py_button );
270
271         script->py_draw = script->py_event = script->py_button = NULL;
272 }
273
274 static int bpy_run_script_init(bContext *C, SpaceScript * sc)
275 {
276         if (sc->script==NULL) 
277                 return 0;
278         
279         if (sc->script->py_draw==NULL && sc->script->scriptname[0] != '\0')
280                 BPY_run_python_script(C, sc->script->scriptname, NULL, NULL);
281                 
282         if (sc->script->py_draw==NULL)
283                 return 0;
284         
285         return 1;
286 }
287
288 int BPY_run_script_space_draw(struct bContext *C, SpaceScript * sc)
289 {
290         if (bpy_run_script_init(C, sc)) {
291                 PyGILState_STATE gilstate = PyGILState_Ensure();
292                 PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
293                 
294                 if (result==NULL)
295                         exit_pydraw(sc, 1);
296                         
297                 PyGILState_Release(gilstate);
298         }
299         return 1;
300 }
301
302 // XXX - not used yet, listeners dont get a context
303 int BPY_run_script_space_listener(bContext *C, SpaceScript * sc)
304 {
305         if (bpy_run_script_init(C, sc)) {
306                 PyGILState_STATE gilstate = PyGILState_Ensure();
307                 
308                 PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
309                 
310                 if (result==NULL)
311                         exit_pydraw(sc, 1);
312                         
313                 PyGILState_Release(gilstate);
314         }
315         return 1;
316 }
317
318 void BPY_DECREF(void *pyob_ptr)
319 {
320         Py_DECREF((PyObject *)pyob_ptr);
321 }
322
323 #if 0
324 /* called from the the scripts window, assume context is ok */
325 int BPY_run_python_script_space(const char *modulename, const char *func)
326 {
327         PyObject *py_dict, *py_result= NULL;
328         char pystring[512];
329         PyGILState_STATE gilstate;
330         
331         /* for calling the module function */
332         PyObject *py_func, 
333         
334         gilstate = PyGILState_Ensure();
335         
336         py_dict = CreateGlobalDictionary(C);
337         
338         PyObject *module = PyImport_ImportModule(scpt->script.filename);
339         if (module==NULL) {
340                 PyErr_SetFormat(PyExc_SystemError, "could not import '%s'", scpt->script.filename);
341         }
342         else {
343                 py_func = PyObject_GetAttrString(modulename, func);
344                 if (py_func==NULL) {
345                         PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func);
346                 }
347                 else {
348                         Py_DECREF(py_func);
349                         if (!PyCallable_Check(py_func)) {
350                                 PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func);
351                         }
352                         else {
353                                 py_result= PyObject_CallObject(py_func, NULL); // XXX will need args eventually
354                         }
355                 }
356         }
357         
358         if (!py_result) {
359                 BPy_errors_to_report(NULL); // TODO - reports
360         } else
361                 Py_DECREF( py_result );
362         
363         Py_XDECREF(module);
364         
365         Py_DECREF(py_dict);
366         
367         PyGILState_Release(gilstate);
368         return 1;
369 }
370 #endif
371
372 // #define TIME_REGISTRATION
373
374 #ifdef TIME_REGISTRATION
375 #include "PIL_time.h"
376 #endif
377
378 /* XXX this is temporary, need a proper script registration system for 2.5 */
379 void BPY_run_ui_scripts(bContext *C, int reload)
380 {
381 #ifdef TIME_REGISTRATION
382         double time = PIL_check_seconds_timer();
383 #endif
384         DIR *dir; 
385         struct dirent *de;
386         char *file_extension;
387         char *dirname;
388         char path[FILE_MAX];
389         char *dirs[] = {"io", "ui", NULL};
390         int a, filelen; /* filename length */
391         
392         PyGILState_STATE gilstate;
393         PyObject *mod;
394         PyObject *sys_path_orig;
395         PyObject *sys_path_new;
396
397         gilstate = PyGILState_Ensure();
398         
399         // XXX - evil, need to access context
400         BPy_SetContext(C);
401         bpy_import_main_set(CTX_data_main(C));
402
403         for(a=0; dirs[a]; a++) {
404                 dirname= BLI_gethome_folder(dirs[a]);
405
406                 if(!dirname)
407                         continue;
408
409                 dir = opendir(dirname);
410
411                 if(!dir)
412                         continue;
413
414                 /* backup sys.path */
415                 sys_path_orig= PySys_GetObject("path");
416                 Py_INCREF(sys_path_orig); /* dont free it */
417                 
418                 sys_path_new= PyList_New(1);
419                 PyList_SET_ITEM(sys_path_new, 0, PyUnicode_FromString(dirname));
420                 PySys_SetObject("path", sys_path_new);
421                 Py_DECREF(sys_path_new);
422                         
423                 while((de = readdir(dir)) != NULL) {
424                         /* We could stat the file but easier just to let python
425                          * import it and complain if theres a problem */
426                         
427                         file_extension = strstr(de->d_name, ".py");
428                         
429                         if(file_extension && *(file_extension + 3) == '\0') {
430                                 filelen = strlen(de->d_name);
431                                 BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
432                                 
433                                 mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0);
434                                 if (mod) {
435                                         if (reload) {
436                                                 PyObject *mod_orig= mod;
437                                                 mod= PyImport_ReloadModule(mod);
438                                                 Py_DECREF(mod_orig);
439                                         }
440                                 }
441                                 
442                                 if(mod) {
443                                         Py_DECREF(mod); /* could be NULL from reloading */
444                                 } else {
445                                         BPy_errors_to_report(NULL); // TODO - reports
446                                         fprintf(stderr, "unable to import \"%s\"  %s/%s\n", path, dirname, de->d_name);
447                                 }
448
449                         }
450                 }
451
452                 closedir(dir);
453
454                 PySys_SetObject("path", sys_path_orig);
455                 Py_DECREF(sys_path_orig);
456         }
457         
458         bpy_import_main_set(NULL);
459         
460         PyGILState_Release(gilstate);
461 #ifdef TIME_REGISTRATION
462         printf("script time %f\n", (PIL_check_seconds_timer()-time));
463 #endif
464 }
465
466 /* ****************************************** */
467 /* Drivers - PyExpression Evaluation */
468
469 /* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */
470 PyObject *bpy_pydriver_Dict = NULL;
471
472 /* For faster execution we keep a special dictionary for pydrivers, with
473  * the needed modules and aliases. 
474  */
475 static int bpy_pydriver_create_dict(void)
476 {
477         PyObject *d, *mod;
478         
479         /* validate namespace for driver evaluation */
480         if (bpy_pydriver_Dict) return -1;
481
482         d = PyDict_New();
483         if (d == NULL) 
484                 return -1;
485         else
486                 bpy_pydriver_Dict = d;
487
488         /* import some modules: builtins, bpy, math, (Blender.noise )*/
489         PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
490
491         mod = PyImport_ImportModule("math");
492         if (mod) {
493                 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
494                 
495                 /* Only keep for backwards compat! - just import all math into root, they are standard */
496                 PyDict_SetItemString(d, "math", mod);
497                 PyDict_SetItemString(d, "m", mod);
498                 Py_DECREF(mod);
499         } 
500         
501         /* add bpy to global namespace */
502         mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
503         if (mod) {
504                 PyDict_SetItemString(bpy_pydriver_Dict, "bpy", mod);
505                 Py_DECREF(mod);
506         }
507         
508         
509 #if 0 // non existant yet
510         mod = PyImport_ImportModule("Blender.Noise");
511         if (mod) {
512                 PyDict_SetItemString(d, "noise", mod);
513                 PyDict_SetItemString(d, "n", mod);
514                 Py_DECREF(mod);
515         } else {
516                 PyErr_Clear();
517         }
518         
519         /* If there's a Blender text called pydrivers.py, import it.
520          * Users can add their own functions to this module. 
521          */
522         if (G.f & G_DOSCRIPTLINKS) {
523                 mod = importText("pydrivers"); /* can also use PyImport_Import() */
524                 if (mod) {
525                         PyDict_SetItemString(d, "pydrivers", mod);
526                         PyDict_SetItemString(d, "p", mod);
527                         Py_DECREF(mod);
528                 } else {
529                         PyErr_Clear();
530                 }
531         }
532 #endif // non existant yet
533         
534         return 0;
535 }
536
537 /* Update function, it gets rid of pydrivers global dictionary, forcing
538  * BPY_pydriver_eval to recreate it. This function is used to force
539  * reloading the Blender text module "pydrivers.py", if available, so
540  * updates in it reach pydriver evaluation. 
541  */
542 void BPY_pydriver_update(void)
543 {
544         PyGILState_STATE gilstate = PyGILState_Ensure();
545
546         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
547                 PyDict_Clear(bpy_pydriver_Dict);
548                 Py_DECREF(bpy_pydriver_Dict);
549                 bpy_pydriver_Dict = NULL;
550         }
551
552         PyGILState_Release(gilstate);
553
554         return;
555 }
556
557 /* error return function for BPY_eval_pydriver */
558 static float pydriver_error(ChannelDriver *driver) 
559 {
560         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
561                 PyDict_Clear(bpy_pydriver_Dict);
562                 Py_DECREF(bpy_pydriver_Dict);
563                 bpy_pydriver_Dict = NULL;
564         }
565
566         driver->flag |= DRIVER_FLAG_INVALID; /* py expression failed */
567         fprintf(stderr, "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n", driver->expression);
568         
569         BPy_errors_to_report(NULL); // TODO - reports
570
571         return 0.0f;
572 }
573
574 /* This evals py driver expressions, 'expr' is a Python expression that
575  * should evaluate to a float number, which is returned. 
576  */
577 float BPY_pydriver_eval (ChannelDriver *driver)
578 {
579         PyObject *driver_vars=NULL;
580         PyObject *retval;
581         PyGILState_STATE gilstate;
582         
583         DriverTarget *dtar;
584         float result = 0.0f; /* default return */
585         char *expr = NULL;
586         short targets_ok= 1;
587         
588         /* sanity checks - should driver be executed? */
589         if ((driver == NULL) /*|| (G.f & G_DOSCRIPTLINKS)==0*/) 
590                 return result;
591         
592         /* get the py expression to be evaluated */
593         expr = driver->expression; 
594         if ((expr == NULL) || (expr[0]=='\0')) 
595                 return result;
596
597         gilstate = PyGILState_Ensure();
598         
599         /* init global dictionary for py-driver evaluation settings */
600         if (!bpy_pydriver_Dict) {
601                 if (bpy_pydriver_create_dict() != 0) {
602                         fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
603                         PyGILState_Release(gilstate);
604                         return result;
605                 }
606         }
607         
608         /* add target values to a dict that will be used as '__locals__' dict */
609         driver_vars = PyDict_New(); // XXX do we need to decref this?
610         for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
611                 PyObject *driver_arg = NULL;
612                 float tval = 0.0f;
613                 
614                 /* try to get variable value */
615                 tval= driver_get_target_value(driver, dtar);
616                 driver_arg= PyFloat_FromDouble((double)tval);
617                 
618                 /* try to add to dictionary */
619                 if (PyDict_SetItemString(driver_vars, dtar->name, driver_arg)) {
620                         /* this target failed - bad name */
621                         if (targets_ok) {
622                                 /* first one - print some extra info for easier identification */
623                                 fprintf(stderr, "\nBPY_pydriver_eval() - Error while evaluating PyDriver:\n");
624                                 targets_ok= 0;
625                         }
626                         
627                         fprintf(stderr, "\tBPY_pydriver_eval() - couldn't add variable '%s' to namespace \n", dtar->name);
628                         BPy_errors_to_report(NULL); // TODO - reports
629                 }
630         }
631         
632         /* execute expression to get a value */
633         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
634         
635         /* decref the driver vars first...  */
636         Py_DECREF(driver_vars);
637         
638         /* process the result */
639         if (retval == NULL) {
640                 result = pydriver_error(driver);
641                 PyGILState_Release(gilstate);
642                 return result;
643         }
644
645         result = (float)PyFloat_AsDouble(retval);
646         Py_DECREF(retval);
647         
648         if ((result == -1) && PyErr_Occurred()) {
649                 result = pydriver_error(driver);
650                 PyGILState_Release(gilstate);
651                 return result;
652         }
653         
654         /* all fine, make sure the "invalid expression" flag is cleared */
655         driver->flag &= ~DRIVER_FLAG_INVALID;
656
657         PyGILState_Release(gilstate);
658
659         return result;
660 }