29ef6c5da1d28ea371231857bca7931773294887
[blender.git] / source / blender / python / BPY_interface.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * This is a new part of Blender.
24  *
25  * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney,
26  * Chris Keith, Chris Want, Ken Hughes
27  *
28  * ***** END GPL LICENSE BLOCK *****
29 */
30
31 #include <Python.h>
32
33 #include "compile.h"            /* for the PyCodeObject */
34 #include "eval.h"               /* for PyEval_EvalCode */
35 #include "BLI_blenlib.h"        /* for BLI_last_slash() */
36 #include "BIF_interface.h"      /* for pupmenu() */
37 #include "BIF_space.h"
38 #include "BIF_screen.h"
39 #include "BIF_toolbox.h"
40 #include "BKE_action.h"         /* for get_pose_channel() */
41 #include "BKE_library.h"
42 #include "BKE_object.h"         /* during_scriptlink() */
43 #include "BKE_text.h"
44 #include "BKE_constraint.h" /* for bConstraintOb */
45 #include "BKE_idprop.h"
46
47 #include "DNA_curve_types.h" /* for struct IpoDriver */
48 #include "DNA_ID.h" /* ipo driver */
49 #include "DNA_object_types.h" /* ipo driver */
50 #include "DNA_constraint_types.h" /* for pyconstraint */
51
52 #include "DNA_screen_types.h"
53 #include "DNA_userdef_types.h"  /* for U.pythondir */
54 #include "MEM_guardedalloc.h"
55 #include "BPY_extern.h"
56 #include "BPY_menus.h"
57 #include "DNA_space_types.h"
58 #include "BKE_global.h"
59 #include "BKE_main.h"
60 #include "BKE_armature.h"
61 #include "BKE_depsgraph.h"
62 #include "api2_2x/EXPP_interface.h"
63 #include "api2_2x/constant.h"
64 #include "api2_2x/gen_utils.h"
65 #include "api2_2x/gen_library.h" /* GetPyObjectFromID */
66 #include "api2_2x/BGL.h" 
67 #include "api2_2x/Blender.h"
68 #include "api2_2x/Camera.h"
69 #include "api2_2x/Draw.h"
70 #include "api2_2x/Object.h"
71 #include "api2_2x/Registry.h"
72 #include "api2_2x/Pose.h"
73 #include "api2_2x/bpy.h" /* for the new "bpy" module */
74
75 /*these next two are for pyconstraints*/
76 #include "api2_2x/IDProp.h"
77 #include "api2_2x/matrix.h"
78
79 /* for scriptlinks */
80 #include "DNA_lamp_types.h"
81 #include "DNA_camera_types.h"
82 #include "DNA_world_types.h"
83 #include "DNA_scene_types.h"
84 #include "DNA_material_types.h"
85
86 /* bpy_registryDict is declared in api2_2x/Registry.h and defined
87  * in api2_2x/Registry.c
88  * This Python dictionary will be used to store data that scripts
89  * choose to preserve after they are executed, so user changes can be
90  * restored next time the script is used.  Check the Blender.Registry module. 
91  */
92 /*#include "api2_2x/Registry.h" */
93
94 /* for pydrivers (ipo drivers defined by one-line Python expressions) */
95 PyObject *bpy_pydriver_Dict = NULL;
96 PyObject *bpy_orig_syspath_List = NULL;
97
98
99 /*
100  * set up a weakref list for Armatures
101  *    creates list in __main__ module dict 
102  */
103   
104 static int setup_armature_weakrefs()
105 {
106         PyObject *maindict;
107         PyObject *main_module;
108         char *list_name = ARM_WEAKREF_LIST_NAME;
109
110         main_module = PyImport_AddModule( "__main__");
111         if(main_module){
112                 PyObject *weakreflink;
113                 maindict= PyModule_GetDict(main_module);
114
115                 /* check if there is already a dict entry for the armature weakrefs,
116                  * and delete if so before making another one */
117
118                 weakreflink= PyDict_GetItemString(maindict,list_name);
119                 if( weakreflink != NULL ) {
120                         PyDict_DelItemString(maindict,list_name);
121                         Py_XDECREF( weakreflink );
122                 }
123
124                 if (PyDict_SetItemString(maindict, 
125                                                                  list_name, 
126                                                                  PyList_New(0)) == -1){
127                         printf("Oops - setup_armature_weakrefs()\n");
128                         
129                         return 0;
130                 }
131         }
132         return 1;
133 }
134
135 /* Declares the modules and their initialization functions
136  * These are TOP-LEVEL modules e.g. import `module` - there is no
137  * support for packages here e.g. import `package.module` */
138
139 static struct _inittab BPy_Inittab_Modules[] = {
140         {"Blender", M_Blender_Init},
141         {"bpy", m_bpy_init},
142         {NULL, NULL}
143 };
144
145 /*************************************************************************
146 * Structure definitions 
147 **************************************************************************/
148 #define FILENAME_LENGTH 24
149
150 typedef struct _ScriptError {
151         char filename[FILENAME_LENGTH];
152         int lineno;
153 } ScriptError;
154
155 /****************************************************************************
156 * Global variables 
157 ****************************************************************************/
158 ScriptError g_script_error;
159
160 /***************************************************************************
161 * Function prototypes 
162 ***************************************************************************/
163 static PyObject *RunPython( Text * text, PyObject * globaldict );
164 static PyObject *CreateGlobalDictionary( void );
165 static void ReleaseGlobalDictionary( PyObject * dict );
166 static void DoAllScriptsFromList( ListBase * list, short event );
167 static PyObject *importText( char *name );
168 static void init_ourImport( void );
169 static void init_ourReload( void );
170 static PyObject *blender_import( PyObject * self, PyObject * args );
171
172
173 static void BPY_Err_Handle( char *script_name );
174 static PyObject *traceback_getFilename( PyObject * tb );
175
176 /****************************************************************************
177 * Description: This function will start the interpreter and load all modules
178 * as well as search for a python installation.
179 ****************************************************************************/
180 void BPY_start_python( int argc, char **argv )
181 {
182         PyThreadState *py_tstate = NULL;
183         static int argc_copy = 0;
184         static char **argv_copy = NULL;
185         int first_time = argc;
186
187         /* we keep a copy of the values of argc and argv so that the game engine
188          * can call BPY_start_python(0, NULL) whenever a game ends, without having
189          * to know argc and argv there (in source/blender/src/space.c) */
190         if( first_time ) {
191                 argc_copy = argc;
192                 argv_copy = argv;
193         }
194
195         //stuff for Registry module
196         bpy_registryDict = PyDict_New(  );/* check comment at start of this file */
197         if( !bpy_registryDict )
198                 printf( "Warning: Couldn't create the Registry Python Dictionary!" );
199         Py_SetProgramName( "blender" );
200
201         /* Py_Initialize() will attempt to import the site module and
202          * print an error if not found.  See init_syspath() for the
203          * rest of our init msgs.
204          */
205
206         /* print Python version
207          * Py_GetVersion() returns a ptr to a static string "9.9.9 (aaaa..." 
208          */
209         {
210                 int count = 3;  /* a nice default for major.minor.  example 2.5 */
211                 const char *version = Py_GetVersion();
212                 /* we know a blank is there somewhere! */
213                 char *blank_ptr = strchr( version, ' '); 
214                 if(blank_ptr)
215                         count = blank_ptr - version;
216                 
217                 printf( "Compiled with Python version %.*s.\n", count, version );
218         }
219
220
221         //Initialize the TOP-LEVEL modules
222         PyImport_ExtendInittab(BPy_Inittab_Modules);
223         
224         //Start the interpreter
225         Py_Initialize(  );
226         
227         PySys_SetArgv( argc_copy, argv_copy );
228         /* Initialize thread support (also acquires lock) */
229         PyEval_InitThreads();
230         
231         //Overrides __import__
232         init_ourImport(  );
233         init_ourReload(  );
234
235         //init a global dictionary
236         g_blenderdict = NULL;
237
238         //Look for a python installation
239         init_syspath( first_time ); /* not first_time: some msgs are suppressed */
240         py_tstate = PyGILState_GetThisThreadState();
241         PyEval_ReleaseThread(py_tstate);
242
243         return;
244 }
245
246 /*****************************************************************************/
247 /* Description: This function will terminate the Python interpreter          */
248 /*****************************************************************************/
249 void BPY_end_python( void )
250 {
251         Script *script = NULL;
252         Script *next_script = NULL;
253
254         PyGILState_Ensure(); /* finalizing, no need to grab the state */
255
256         if( bpy_registryDict ) {
257                 Py_DECREF( bpy_registryDict );
258                 bpy_registryDict = NULL;
259         }
260
261         if( bpy_pydriver_Dict ) {
262                 Py_DECREF( bpy_pydriver_Dict );
263                 bpy_pydriver_Dict = NULL;
264         }
265         
266         if( bpy_orig_syspath_List ) {
267                 Py_DECREF( bpy_orig_syspath_List );
268                 bpy_orig_syspath_List = NULL;
269         }
270
271         /* Freeing all scripts here prevents problems with the order in which
272          * Python is finalized and G.main is freed in exit_usiblender() */
273         for (script = G.main->script.first; script; script = next_script) {
274                 next_script = script->id.next;
275                 free_libblock( &G.main->script, script );
276         }
277
278         Py_Finalize(  );
279
280         BPyMenu_RemoveAllEntries(  );   /* freeing bpymenu mem */
281
282         /* a script might've opened a .blend file but didn't close it, so: */
283         EXPP_Library_Close(  );
284
285         return;
286 }
287
288 void syspath_append( char *dirname )
289 {
290         PyObject *mod_sys= NULL, *dict= NULL, *path= NULL, *dir= NULL;
291         short ok=1;
292
293         mod_sys = PyImport_ImportModule( "sys" );       /* new ref */
294         
295         if (mod_sys) {
296                 dict = PyModule_GetDict( mod_sys );     /* borrowed ref */
297                 path = PyDict_GetItemString( dict, "path" );    /* borrowed ref */
298                 if ( !PyList_Check( path ) ) {
299                         ok = 0;
300                 }
301         } else {
302                 /* cant get the sys module */
303                 /* PyErr_Clear(); is called below */
304                 ok = 0;
305         }
306         
307         dir = PyString_FromString( dirname );
308         
309         if (ok && PySequence_Contains(path, dir)==0) { /* Only add if we need to */
310                 if (PyList_Append( path, dir ) != 0) /* decref below */
311                         ok = 0; /* append failed */
312         }
313         
314         if( (ok==0) || PyErr_Occurred(  ) )
315                 fprintf(stderr, "Warning: could import or build sys.path\n" );
316         
317         PyErr_Clear();
318         Py_DECREF( dir );
319         Py_XDECREF( mod_sys );
320 }
321
322 void init_syspath( int first_time )
323 {
324         PyObject *mod, *d;
325         char *progname;
326         char execdir[FILE_MAXDIR];      /*defines from DNA_space_types.h */
327
328         int n;
329
330         mod = PyImport_ImportModule( "Blender.sys" );
331
332         if( mod ) {
333                 d = PyModule_GetDict( mod );
334                 EXPP_dict_set_item_str( d, "progname", PyString_FromString( bprogname ) );
335                 Py_DECREF( mod );
336         } else {
337                 printf( "Warning: could not set Blender.sys\n" );
338                 PyErr_Clear();
339         }
340
341         progname = BLI_last_slash( bprogname ); /* looks for the last dir separator */
342
343         n = progname - bprogname;
344         if( n > 0 ) {
345                 strncpy( execdir, bprogname, n );
346                 if( execdir[n - 1] == '.' )
347                         n--;    /*fix for when run as ./blender */
348                 execdir[n] = '\0';
349
350                 syspath_append( execdir );      /* append to module search path */
351         } else {
352                 printf( "Warning: could not determine argv[0] path\n" );
353         }
354         
355         /* 
356            attempt to import 'site' module as a check for valid
357            python install found.
358         */
359
360         printf("Checking for installed Python... "); /* appears after msg "Compiled with Python 2.x"  */
361         mod = PyImport_ImportModule( "site" );  /* new ref */
362
363         if( mod ) {
364                 printf("got it!\n");  
365                 Py_DECREF( mod );
366         } else {                /* import 'site' failed */
367                 PyErr_Clear(  );
368                 if( first_time ) {
369                         printf( "No installed Python found.\n" );
370                         printf( "Only built-in modules are available.  Some scripts may not run.\n" );
371                         printf( "Continuing happily.\n" );
372                 }
373         }
374
375
376         /* 
377          * initialize the sys module
378          * set sys.executable to the Blender exe 
379          */
380
381         mod = PyImport_ImportModule( "sys" );   /* new ref */
382
383         if( mod ) {
384                 d = PyModule_GetDict( mod );    /* borrowed ref */
385                 EXPP_dict_set_item_str( d, "executable", Py_BuildValue( "s", bprogname ) );
386                 
387                 if (bpy_orig_syspath_List == NULL) {
388                         /* backup the original sys.path to rebuild later */     
389                         PyObject *syspath = PyDict_GetItemString( d, "path" );  /* borrowed ref */
390                         if (bpy_orig_syspath_List) { /* This should never happen but just incase, be nice */
391                                 Py_DECREF(bpy_orig_syspath_List);
392                         }
393                         bpy_orig_syspath_List = PyList_GetSlice(syspath, 0, PyList_Size(syspath));
394                 }
395                 
396                 Py_DECREF( mod );
397         } else{
398                 PyErr_Clear( );
399                 printf("Warning: import of sys module failed\n");
400         }
401 }
402
403 void BPY_rebuild_syspath( void )
404 {
405         PyObject *mod, *dict, *syspath;
406         char dirpath[FILE_MAX];
407         char *sdir = NULL;
408         PyGILState_STATE gilstate = PyGILState_Ensure();
409
410         mod = PyImport_ImportModule( "sys" );   
411         if (!mod) {
412                 printf("Warning: could not import python sys module. some modules may not import.\n");
413                 PyErr_Clear(  );
414                 PyGILState_Release(gilstate);
415                 return;
416         }
417         
418         if (!bpy_orig_syspath_List) { /* should never happen */
419                 printf("Warning: cant refresh python path, bpy_orig_syspath_List is NULL\n");
420                 Py_DECREF(mod);
421                 PyGILState_Release(gilstate);
422                 return;
423         }
424         
425         dict = PyModule_GetDict( mod ); /* borrowed ref */
426         
427         /* Reset sys.path */    
428         syspath = PyDict_GetItemString( dict, "path" ); /* borrowed ref */
429         PyList_SetSlice(syspath, 0, PyList_Size(syspath), bpy_orig_syspath_List);
430         
431         if(U.pythondir[0] != '\0' ) {
432                 char modpath[FILE_MAX];
433                 int upyslen = strlen(U.pythondir);
434                 BLI_strncpy(dirpath, U.pythondir, FILE_MAX);
435                 
436                 /* check if user pydir ends with a slash and, if so, remove the slash
437                  * (for eventual implementations of c library's stat function that might
438                  * not like it) */
439 #ifdef WIN32
440                 if (upyslen > 3) {
441 #else
442                 if (upyslen > 1) {
443 #endif
444                         if (dirpath[upyslen-1] == '\\' || dirpath[upyslen-1] == '/') {
445                                 dirpath[upyslen-1] = '\0';
446                         }
447                 }
448
449                 BLI_convertstringcode(dirpath, G.sce);
450                 syspath_append(dirpath);        /* append to module search path */
451                 BLI_join_dirfile( modpath, dirpath, "bpymodules" );
452                 if (BLI_exists(modpath)) syspath_append(modpath);
453         }
454         
455         sdir = bpy_gethome(1);
456         if (sdir) {
457                 syspath_append(sdir);
458                 BLI_make_file_string("/", dirpath, sdir, "bpymodules");
459                 if (BLI_exists(dirpath)) syspath_append(dirpath);
460         }
461         
462         Py_DECREF(mod);
463         PyGILState_Release(gilstate);
464 }
465
466 int BPY_path_update( void )
467 {
468         BPyMenu_RemoveAllEntries(); /* free old data */
469         BPY_rebuild_syspath();
470         if (BPyMenu_Init(1) == -1) { /* re-eval scripts registration in menus */
471                 return 0;
472         }
473         return 1;
474 }
475
476 /****************************************************************************
477 * Description: This function finishes Python initialization in Blender.  
478
479 Because U.pythondir (user defined dir for scripts) isn't         
480 initialized when BPY_start_Python needs to be executed, we       
481 postpone adding U.pythondir to sys.path and also BPyMenus         
482 (mechanism to register scripts in Blender menus) for when  
483 that dir info is available.   
484 ****************************************************************************/
485 void BPY_post_start_python( void )
486 {
487         PyGILState_STATE gilstate = PyGILState_Ensure();
488
489         BPY_rebuild_syspath();
490         BPyMenu_Init( 0 );      /* get dynamic menus (registered scripts) data */
491
492         PyGILState_Release(gilstate);
493 }
494
495 /****************************************************************************
496 * Description: This function will return the linenumber on which an error  
497 *               has occurred in the Python script.                      
498 ****************************************************************************/
499 int BPY_Err_getLinenumber( void )
500 {
501         return g_script_error.lineno;
502 }
503
504 /*****************************************************************************/
505 /* Description: This function will return the filename of the python script. */
506 /*****************************************************************************/
507 const char *BPY_Err_getFilename( void )
508 {
509         return g_script_error.filename;
510 }
511
512 /*****************************************************************************/
513 /* Description: Return PyString filename from a traceback object            */
514 /*****************************************************************************/
515 static PyObject *traceback_getFilename( PyObject * tb )
516 {
517         PyObject *v = NULL;
518
519 /* co_filename is in f_code, which is in tb_frame, which is in tb */
520
521         v = PyObject_GetAttrString( tb, "tb_frame" );
522         if (v) {
523                 Py_DECREF( v );
524                 v = PyObject_GetAttrString( v, "f_code" );
525                 if (v) {
526                         Py_DECREF( v );
527                         v = PyObject_GetAttrString( v, "co_filename" );
528                 }
529         }
530
531         if (v) return v;
532         else return PyString_FromString("unknown");
533 }
534
535 /****************************************************************************
536 * Description: Blender Python error handler. This catches the error and 
537 * stores filename and line number in a global  
538 *****************************************************************************/
539 static void BPY_Err_Handle( char *script_name )
540 {
541         PyObject *exception, *err, *tb, *v;
542
543         if( !script_name ) {
544                 printf( "Error: script has NULL name\n" );
545                 return;
546         }
547
548         PyErr_Fetch( &exception, &err, &tb );
549
550         if (!script_name) script_name = "untitled";
551         //if( !exception && !tb ) {
552         //      printf( "FATAL: spurious exception\n" );
553         //      return;
554         //}
555
556         strcpy( g_script_error.filename, script_name );
557
558         if( exception
559             && PyErr_GivenExceptionMatches( exception, PyExc_SyntaxError ) ) {
560                 /* no traceback available when SyntaxError */
561                 PyErr_NormalizeException( &exception, &err, &tb );
562                 PyErr_Restore( exception, err, tb );    /* takes away reference! */
563                 PyErr_Print(  );
564                 v = PyObject_GetAttrString( err, "lineno" );
565                 if( v ) {
566                         g_script_error.lineno = PyInt_AsLong( v );
567                         Py_DECREF( v );
568                 } else {
569                         g_script_error.lineno = -1;
570                 }
571                 /* this avoids an abort in Python 2.3's garbage collecting: */
572                 PyErr_Clear(  );
573                 return;
574         } else {
575                 PyErr_NormalizeException( &exception, &err, &tb );
576                 PyErr_Restore( exception, err, tb );    /* takes away reference! */
577                 PyErr_Print(  );
578                 tb = PySys_GetObject( "last_traceback" );
579
580                 if( !tb ) {
581                         printf( "\nCan't get traceback\n" );
582                         return;
583                 }
584
585                 Py_INCREF( tb );
586
587 /* From old bpython BPY_main.c:
588  * 'check traceback objects and look for last traceback in the
589  *      same text file. This is used to jump to the line of where the
590  *      error occured. "If the error occured in another text file or module,
591  *      the last frame in the current file is adressed."' 
592  */
593
594                 for(;;) {
595                         v = PyObject_GetAttrString( tb, "tb_next" );
596
597                         if( !v || v == Py_None ||
598                                 strcmp(PyString_AsString(traceback_getFilename(v)), script_name)) {
599                                 break;
600                         }
601
602                         Py_DECREF( tb );
603                         tb = v;
604                 }
605
606                 v = PyObject_GetAttrString( tb, "tb_lineno" );
607                 if (v) {
608                         g_script_error.lineno = PyInt_AsLong(v);
609                         Py_DECREF(v);
610                 }
611                 v = traceback_getFilename( tb );
612                 if (v) {
613                         strncpy( g_script_error.filename, PyString_AsString( v ),
614                                 FILENAME_LENGTH );
615                         Py_DECREF(v);
616                 }
617                 Py_DECREF( tb );
618         }
619
620         return;
621 }
622
623 /****************************************************************************
624 * Description: This function executes the script passed by st.          
625 * Notes:        It is called by blender/src/drawtext.c when a Blender user  
626 *               presses ALT+PKEY in the script's text window. 
627 *****************************************************************************/
628 int BPY_txt_do_python_Text( struct Text *text )
629 {
630         PyObject *py_dict, *py_result;
631         BPy_constant *info;
632         char textname[24];
633         Script *script = G.main->script.first;
634         PyGILState_STATE gilstate;
635
636         if( !text )
637                 return 0;
638
639         /* check if this text is already running */
640         while( script ) {
641                 if( !strcmp( script->id.name + 2, text->id.name + 2 ) ) {
642                         /* if this text is already a running script, 
643                          * just move to it: */
644                         if (!G.background) {
645                                 SpaceScript *sc;
646                                 newspace( curarea, SPACE_SCRIPT );
647                                 sc = curarea->spacedata.first;
648                                 sc->script = script;
649                                 return 1;
650                         }
651                 }
652                 script = script->id.next;
653         }
654
655         /* Create a new script structure and initialize it: */
656         script = alloc_libblock( &G.main->script, ID_SCRIPT, text->id.name+2 );
657
658         if( !script ) {
659                 printf( "couldn't allocate memory for Script struct!" );
660                 return 0;
661         }
662
663         /* if in the script Blender.Load(blendfile) is not the last command,
664          * an error after it will call BPY_Err_Handle below, but the text struct
665          * will have been deallocated already, so we need to copy its name here.
666          */
667         BLI_strncpy( textname, text->id.name+2, 21 );
668
669         script->id.us = 1;
670         script->flags = SCRIPT_RUNNING;
671         script->py_draw = NULL;
672         script->py_event = NULL;
673         script->py_button = NULL;
674         script->py_browsercallback = NULL;
675         strncpy(script->scriptname, text->id.name+2, sizeof(script->scriptname));
676         gilstate = PyGILState_Ensure();
677
678         py_dict = CreateGlobalDictionary(  );
679
680         if( !setup_armature_weakrefs()){
681                 printf("Oops - weakref dict\n");
682                 PyGILState_Release(gilstate);
683                 return 0;
684         }
685
686         script->py_globaldict = py_dict;
687
688         info = ( BPy_constant * ) PyConstant_New(  );
689         if( info ) {
690                 PyConstant_Insert( info, "name",
691                                  PyString_FromString( script->id.name + 2 ) );
692                 Py_INCREF( Py_None );
693                 PyConstant_Insert( info, "arg", Py_None );
694                 EXPP_dict_set_item_str( py_dict, "__script__",
695                                       ( PyObject * ) info );
696         }
697
698         py_result = RunPython( text, py_dict ); /* Run the script */
699
700         if( !py_result ) {      /* Failed execution of the script */
701
702                 BPY_Err_Handle( textname );
703                 ReleaseGlobalDictionary( py_dict );
704                 script->py_globaldict = NULL;
705                 free_libblock( &G.main->script, script );
706                 PyGILState_Release(gilstate);
707                 return 0;
708         } else {
709                 Py_DECREF( py_result );
710                 script->flags &= ~SCRIPT_RUNNING;
711                 if( !script->flags ) {
712                         ReleaseGlobalDictionary( py_dict );
713                         script->py_globaldict = NULL;
714                         free_libblock( &G.main->script, script );
715                 }
716         }
717
718         PyGILState_Release(gilstate);
719
720         return 1;               /* normal return */
721 }
722
723 /****************************************************************************
724 * Description: Called from command line to run a Python script
725 * automatically. The script can be a file or a Blender Text in the current 
726 * .blend.
727 ****************************************************************************/
728 void BPY_run_python_script( const char *fn )
729 {
730         char filename[FILE_MAXDIR + FILE_MAXFILE];
731         Text *text = NULL;
732         int is_blender_text = 0;
733         
734         BLI_strncpy(filename, fn, FILE_MAXDIR + FILE_MAXFILE);
735         
736         if (!BLI_exists(filename))
737                 BLI_convertstringcwd(filename);
738                 
739         if (!BLI_exists(filename)) {    /* if there's no such filename ... */
740                 /* try an already existing Blender Text.
741                  * use 'fn' rather then filename for this since were looking for
742                  * internal text
743                  */
744                 text = G.main->text.first;
745
746                 while (text) {
747                         if (!strcmp(fn, text->id.name + 2)) break;
748                         text = text->id.next;
749                 }
750
751                 if (text == NULL) {
752                         printf("\nError: no such file or Blender text -- %s.\n", fn);
753                         return;
754                 }
755                 else is_blender_text = 1;       /* fn is already a Blender Text */
756         }
757
758         else {
759                 /* use filename here since we know it exists,
760                  * 'fn' may have been a relative path
761                  */
762                 text = add_text(filename);
763
764                 if (text == NULL) {
765                         printf("\nError in BPY_run_python_script:\n"
766                                 "couldn't create Blender text from \"%s\"\n", filename);
767                 /* Chris: On Windows if I continue I just get a segmentation
768                  * violation.  To get a baseline file I exit here. */
769                 exit(2);
770                 /* return; */
771                 }
772         }
773
774         if (BPY_txt_do_python_Text(text) != 1) {
775                 printf("\nError executing Python script from command-line:\n"
776                         "%s (at line %d).\n", fn, BPY_Err_getLinenumber());
777         }
778
779         if (!is_blender_text) {
780                 /* We can't simply free the text, since the script might have called
781                  * Blender.Load() to load a new .blend, freeing previous data.
782                  * So we check if the pointer is still valid. */
783                 if (BLI_findindex(&G.main->text, text) != -1) {
784                         free_libblock(&G.main->text, text);
785                 }
786         }
787 }
788
789 int BPY_run_script(Script *script)
790 {
791         PyObject *py_dict, *py_res, *pyarg;
792         Text *text = NULL;
793         BPy_constant *info;
794         
795         PyGILState_STATE gilstate = PyGILState_Ensure();
796         
797         if (!BLI_exists(script->scriptname)) {
798                 /* The file dosnt exist, maybe this blend file was made on some other persons computer? */
799                 char fname[FILE_MAX];
800                 char fpath[FILE_MAX];
801                 char ftmp[FILE_MAX];
802                 char *bpyhome = bpy_gethome(1);
803                 
804                 if (bpyhome) {
805                         BLI_strncpy(ftmp, script->scriptname, sizeof(ftmp));
806                         BLI_split_dirfile_basic(ftmp, NULL, fname); /* get the filename only - fname */
807                         BLI_strncpy(fpath, bpy_gethome(1), sizeof(fpath));
808                         BLI_add_slash(fpath);
809                         strcat(fpath, fname);
810                 
811                         if (BLI_exists(fpath)) {
812                                 strncpy(script->scriptname, fpath, sizeof(script->scriptname));
813                         } else {
814                                 bpyhome = NULL; /* a bit dodgy, this is so the line below runs */
815                         }
816                 }
817                 
818                 if (bpyhome == NULL && U.pythondir[0]) {
819                         BLI_make_file_string("/", fpath, U.pythondir, fname);
820                         if (BLI_exists(fpath)) {
821                                 strncpy(script->scriptname, fpath, sizeof(script->scriptname));
822                         }
823                 }
824                 
825                 /* cant find the file?, fallback to text block */
826                 if (!BLI_exists(script->scriptname)) {
827                         for (text=G.main->text.first; text; text=text->id.next) {
828                                 if (strcmp(script->scriptname, text->id.name+2)==0) {
829                                         break;
830                                 }
831                         }
832                 }
833         }
834         if (text) {
835                 Py_INCREF( Py_None );
836                 pyarg = Py_None;
837         } else {
838                 if (!BLI_exists(script->scriptname)) {
839                         printf( "Script does not exit %s\n", script->scriptname );
840                         free_libblock( &G.main->script, script );
841                         PyGILState_Release(gilstate);
842                         return 0;
843                 }
844                 
845                 if( script->scriptarg[0] == '\0' ) { /* no submenus */
846                         Py_INCREF( Py_None );
847                         pyarg = Py_None;
848                 } else {
849                         pyarg = PyString_FromString( script->scriptarg );
850                 }
851         }
852         
853         script->id.us = 1;
854         script->flags = SCRIPT_RUNNING;
855         script->py_draw = NULL;
856         script->py_event = NULL;
857         script->py_button = NULL;
858         script->py_browsercallback = NULL;
859         
860         py_dict = CreateGlobalDictionary(  );
861
862         script->py_globaldict = py_dict;
863
864         if( !setup_armature_weakrefs()){
865                 printf("Oops - weakref dict\n");
866                 free_libblock( &G.main->script, script );
867                 ReleaseGlobalDictionary( py_dict );
868                 PyGILState_Release(gilstate);
869                 return 0;
870         }
871         
872         info = ( BPy_constant * ) PyConstant_New(  );
873         if( info ) {
874                 PyConstant_Insert( info, "name",
875                                  PyString_FromString( script->id.name + 2 ) );
876                 PyConstant_Insert( info, "arg", pyarg );
877                 EXPP_dict_set_item_str( py_dict, "__script__",
878                                       ( PyObject * ) info );
879         }
880         
881         if (text) {
882                 py_res = RunPython( text, py_dict );
883         } else {
884                 char pystring[sizeof(script->scriptname) + 15];
885                 sprintf(pystring, "execfile(r'%s')", script->scriptname);
886                 py_res = PyRun_String( pystring, Py_file_input, py_dict, py_dict );
887         }
888
889         if( !py_res ) {         /* Failed execution of the script */
890                 /* Previously we used PyRun_File to run directly the code on a FILE 
891                 * object, but as written in the Python/C API Ref Manual, chapter 2,
892                 * 'FILE structs for different C libraries can be different and 
893                 * incompatible'.
894                 * So now we load the script file data to a buffer */
895                 BPY_Err_Handle( script->id.name + 2 );
896                 ReleaseGlobalDictionary( py_dict );
897                 script->py_globaldict = NULL;
898                 free_libblock( &G.main->script, script );
899                 error_pyscript(  );
900
901                 PyGILState_Release(gilstate);
902                 return 0;
903         } else {
904                 Py_DECREF( py_res );
905                 script->flags &= ~SCRIPT_RUNNING;
906
907                 if( !script->flags ) {
908                         ReleaseGlobalDictionary( py_dict );
909                         script->py_globaldict = NULL;
910                         free_libblock( &G.main->script, script );
911
912                         /* special case: called from the menu in the Scripts window
913                          * we have to change sc->script pointer, since it'll be freed here.*/
914                         if (!G.background) {
915                                 if( curarea->spacetype == SPACE_SCRIPT ) {
916                                         SpaceScript *sc = curarea->spacedata.first;
917                                         sc->script = G.main->script.first;      /* can be null, which is ok ... */
918                                         /* ... meaning no other script is running right now. */
919                                 }
920                         }
921
922                 }
923         }
924         
925         PyGILState_Release(gilstate);
926         return 1;
927 }
928         
929 /****************************************************************************
930 * Description: This function executes the script chosen from a menu.
931 * Notes:        It is called by the ui code in src/header_???.c when a user  
932 *               clicks on a menu entry that refers to a script.
933 *               Scripts are searched in the BPyMenuTable, using the given
934 *               menutype and event values to know which one was chosen. 
935 *****************************************************************************/
936 int BPY_menu_do_python( short menutype, int event )
937 {
938         BPyMenu *pym;
939         pym = BPyMenu_GetEntry( menutype, ( short ) event );
940         return BPY_menu_invoke( pym, menutype );
941 }
942         
943 /****************************************************************************
944 * Description: This function executes the script by its shortcut.
945 * Notes:        It is called by the ui code in src/???.c when a user presses an
946 *               unassigned key combination. Scripts are searched in the BPyMenuTable,
947 *               using the given menutype and event values to know which one to invoke.
948 *****************************************************************************/
949 int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short qual )
950 {
951         BPyMenu *pym;
952         pym = BPyMenu_GetEntry( menutype, 0 );
953
954         while ( pym ) {
955                 if ( pym->key && pym->key == key && pym->qual == qual ) {
956                         return BPY_menu_invoke( pym, menutype );
957                 }
958                 pym = pym->next;
959         }
960         
961         return 0;
962 }
963
964 /****************************************************************************
965 * Description: This function executes the script described by a menu item.
966 *****************************************************************************/
967 int BPY_menu_invoke( BPyMenu *pym, short menutype )
968 {
969         char *argstr = NULL;
970         BPySubMenu *pysm;
971         char scriptname[21];
972         Script *script = NULL;
973         int ret, len;
974         PyGILState_STATE gilstate;
975         char filestr[FILE_MAX];
976
977         if( !pym )
978                 return 0;
979
980         gilstate = PyGILState_Ensure();
981
982         if( pym->version > G.version )
983                 notice( "Version mismatch: script was written for Blender %d. "
984                         "It may fail with yours: %d.", pym->version,
985                         G.version );
986
987 /* if there are submenus, let the user choose one from a pupmenu that we
988  * create here.*/
989         pysm = pym->submenus;
990         if( pysm ) {
991                 char *pupstr;
992                 int arg;
993
994                 pupstr = BPyMenu_CreatePupmenuStr( pym, menutype );
995
996                 if( pupstr ) {
997                         arg = pupmenu( pupstr );
998                         MEM_freeN( pupstr );
999
1000                         if( arg >= 0 ) {
1001                                 while( arg-- )
1002                                         pysm = pysm->next;
1003                                 argstr = pysm->arg;
1004                         } else {
1005                                 PyGILState_Release(gilstate);
1006                                 return 0;
1007                         }
1008                 }
1009         }
1010
1011         if( pym->dir ) { /* script is in U.pythondir */
1012                 char upythondir[FILE_MAX];
1013
1014                 /* dirs in Blender can be "//", which has a special meaning */
1015                 BLI_strncpy(upythondir, U.pythondir, FILE_MAX);
1016                 BLI_convertstringcode(upythondir, G.sce); /* if so, this expands it */
1017                 BLI_make_file_string( "/", filestr, upythondir, pym->filename );
1018         }
1019         else { /* script is in default scripts dir */
1020                 char *scriptsdir = bpy_gethome(1);
1021
1022                 if (!scriptsdir) {
1023                         printf("Error loading script: can't find default scripts dir!");
1024                         PyGILState_Release(gilstate);
1025                         return 0;
1026                 }
1027
1028                 BLI_make_file_string( "/", filestr, scriptsdir, pym->filename );
1029         }
1030
1031         BLI_strncpy(scriptname, pym->name, 21);
1032         len = strlen(scriptname) - 1;
1033         /* by convention, scripts that open the file browser or have submenus
1034          * display '...'.  Here we remove them from the datablock name */
1035         while ((len > 0) && scriptname[len] == '.') {
1036                 scriptname[len] = '\0';
1037                 len--;
1038         }
1039         
1040         /* Create a new script structure and initialize it: */
1041         script = alloc_libblock( &G.main->script, ID_SCRIPT, scriptname );
1042
1043         if( !script ) {
1044                 printf( "couldn't allocate memory for Script struct!" );
1045                 PyGILState_Release(gilstate);
1046                 return 0;
1047         }
1048
1049         /* let's find a proper area for an eventual script gui:
1050          * (still experimenting here, need definition on which win
1051          * each group will be put to code this properly) */
1052         switch ( menutype ) {
1053
1054         case PYMENU_IMPORT:     /* first 4 were handled in header_info.c */
1055         case PYMENU_EXPORT:
1056         case PYMENU_HELP:
1057         case PYMENU_RENDER:
1058         case PYMENU_WIZARDS:
1059         case PYMENU_SCRIPTTEMPLATE:
1060         case PYMENU_TEXTPLUGIN:
1061         case PYMENU_MESHFACEKEY:
1062                 break;
1063
1064         default:
1065                 if( curarea->spacetype != SPACE_SCRIPT ) {
1066                         ScrArea *sa = NULL;
1067
1068                         sa = find_biggest_area_of_type( SPACE_BUTS );
1069                         if( sa ) {
1070                                 if( ( 1.5 * sa->winx ) < sa->winy )
1071                                         sa = NULL;      /* too narrow? */
1072                         }
1073
1074                         if( !sa )
1075                                 sa = find_biggest_area_of_type( SPACE_SCRIPT );
1076                         if( !sa )
1077                                 sa = find_biggest_area_of_type( SPACE_TEXT );
1078                         if( !sa )
1079                                 sa = find_biggest_area_of_type( SPACE_IMAGE );  /* group UV */
1080                         if( !sa )
1081                                 sa = find_biggest_area_of_type( SPACE_VIEW3D );
1082
1083                         if( !sa )
1084                                 sa = find_biggest_area(  );
1085
1086                         areawinset( sa->win );
1087                 }
1088                 break;
1089         }
1090         
1091         strncpy(script->scriptname, filestr, sizeof(script->scriptname));
1092         if (argstr!=NULL && argstr[0] != '\0')
1093                 strncpy(script->scriptarg, argstr, sizeof(script->scriptarg));
1094         
1095         ret = BPY_run_script(script);
1096
1097         return 1;               /* normal return */
1098 }
1099
1100 /*****************************************************************************
1101 * Description:  
1102 * Notes:
1103 *****************************************************************************/
1104 void BPY_free_compiled_text( struct Text *text )
1105 {
1106         if( text->compiled ) {
1107                 Py_DECREF( ( PyObject * ) text->compiled );
1108                 text->compiled = NULL;
1109         }
1110 }
1111
1112 /*****************************************************************************
1113 * Description: This function frees a finished (flags == 0) script.
1114 *****************************************************************************/
1115 void BPY_free_finished_script( Script * script )
1116 {
1117         PyGILState_STATE gilstate;
1118
1119         if( !script )
1120                 return;
1121
1122         gilstate = PyGILState_Ensure();
1123
1124         if( PyErr_Occurred(  ) ) {      /* if script ended after filesel */
1125                 PyErr_Print(  );        /* eventual errors are handled now */
1126                 error_pyscript(  );
1127         }
1128
1129         PyGILState_Release(gilstate);
1130
1131         free_libblock( &G.main->script, script );
1132         return;
1133 }
1134
1135 static void unlink_script( Script * script )
1136 {       /* copied from unlink_text in drawtext.c */
1137         bScreen *scr;
1138         ScrArea *area;
1139         SpaceLink *sl;
1140
1141         for( scr = G.main->screen.first; scr; scr = scr->id.next ) {
1142                 for( area = scr->areabase.first; area; area = area->next ) {
1143                         for( sl = area->spacedata.first; sl; sl = sl->next ) {
1144                                 if( sl->spacetype == SPACE_SCRIPT ) {
1145                                         SpaceScript *sc = ( SpaceScript * ) sl;
1146
1147                                         if( sc->script == script ) {                                    
1148                                                 sc->script = NULL;
1149
1150                                                 if( sc == area->spacedata.first ) {
1151                                                         scrarea_queue_redraw( area );
1152                                                 }
1153                                                 
1154                                                 if (sc->but_refs) {
1155                                                         BPy_Set_DrawButtonsList(sc->but_refs);
1156                                                         BPy_Free_DrawButtonsList();
1157                                                         sc->but_refs = NULL;
1158                                                 }
1159                                         }
1160                                 }
1161                         }
1162                 }
1163         }
1164 }
1165
1166 /* This is called from free_libblock( &G.main->script, script ); */
1167 void BPY_clear_script( Script * script )
1168 {
1169         PyObject *dict;
1170         PyGILState_STATE gilstate;
1171
1172         if( !script )
1173                 return;
1174
1175         gilstate = PyGILState_Ensure();
1176
1177         if (!Py_IsInitialized()) {
1178                 printf("\nError: trying to free script data after finalizing Python!");
1179                 printf("\nScript name: %s\n", script->id.name+2);
1180                 PyGILState_Release(gilstate);
1181                 return;
1182         }
1183
1184         Py_XDECREF( ( PyObject * ) script->py_draw );
1185         Py_XDECREF( ( PyObject * ) script->py_event );
1186         Py_XDECREF( ( PyObject * ) script->py_button );
1187         Py_XDECREF( ( PyObject * ) script->py_browsercallback );
1188         script->py_draw = NULL;
1189         script->py_event = NULL;
1190         script->py_button = NULL;
1191         script->py_browsercallback = NULL;
1192         script->scriptname[0] = '\0';
1193         script->scriptarg[0] = '\0';
1194         
1195         dict = script->py_globaldict;
1196
1197         if( dict ) {
1198                 PyDict_Clear( dict );
1199                 Py_DECREF( dict );      /* Release dictionary. */
1200                 script->py_globaldict = NULL;
1201         }
1202
1203         PyGILState_Release(gilstate);
1204
1205         unlink_script( script );
1206 }
1207
1208 /* PyDrivers */
1209
1210 /* PyDrivers are Ipo Drivers governed by expressions written in Python.
1211  * Expressions here are one-liners that evaluate to a float value. */
1212
1213 /* For faster execution we keep a special dictionary for pydrivers, with
1214  * the needed modules and aliases. */
1215 static int bpy_pydriver_create_dict(void)
1216 {
1217         PyObject *d, *mod;
1218
1219         if (bpy_pydriver_Dict) return -1;
1220
1221         d = PyDict_New();
1222         if (!d) return -1;
1223
1224         bpy_pydriver_Dict = d;
1225
1226         /* import some modules: builtins, Blender, math, Blender.noise */
1227
1228         PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1229
1230         mod = PyImport_ImportModule("Blender");
1231         if (mod) {
1232                 PyDict_SetItemString(d, "Blender", mod);
1233                 PyDict_SetItemString(d, "b", mod);
1234                 Py_DECREF(mod);
1235         } else {
1236                 PyErr_Clear();
1237         }
1238
1239         mod = PyImport_ImportModule("math");
1240         if (mod) {
1241                 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
1242                 
1243                 /* Only keep for backwards compat! - just import all math into root, they are standard */
1244                 PyDict_SetItemString(d, "math", mod);
1245                 PyDict_SetItemString(d, "m", mod);
1246                 Py_DECREF(mod);
1247         } 
1248
1249         mod = PyImport_ImportModule("Blender.Noise");
1250         if (mod) {
1251                 PyDict_SetItemString(d, "noise", mod);
1252                 PyDict_SetItemString(d, "n", mod);
1253                 Py_DECREF(mod);
1254         } else {
1255                 PyErr_Clear();
1256         }
1257
1258         /* If there's a Blender text called pydrivers.py, import it.
1259          * Users can add their own functions to this module. */
1260         if (G.f&G_DOSCRIPTLINKS) {
1261                 mod = importText("pydrivers"); /* can also use PyImport_Import() */
1262                 if (mod) {
1263                         PyDict_SetItemString(d, "pydrivers", mod);
1264                         PyDict_SetItemString(d, "p", mod);
1265                         Py_DECREF(mod);
1266                 } else {
1267                         PyErr_Clear();
1268                 }
1269         }
1270         /* short aliases for some Get() functions: */
1271
1272         /* ob(obname) == Blender.Object.Get(obname) */
1273         mod = PyImport_ImportModule("Blender.Object");
1274         if (mod) {
1275                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1276                 Py_DECREF(mod);
1277                 if (fcn) {
1278                         PyDict_SetItemString(d, "ob", fcn);
1279                         Py_DECREF(fcn);
1280                 }
1281         } else {
1282                 PyErr_Clear();
1283         }
1284         
1285         /* TODO - change these */
1286         /* me(meshname) == Blender.Mesh.Get(meshname) */
1287         mod = PyImport_ImportModule("Blender.Mesh");
1288         if (mod) {
1289                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1290                 Py_DECREF(mod);
1291                 if (fcn) {
1292                         PyDict_SetItemString(d, "me", fcn);
1293                         Py_DECREF(fcn);
1294                 }
1295         } else {
1296                 PyErr_Clear();
1297         }
1298
1299         /* ma(matname) == Blender.Material.Get(matname) */
1300         mod = PyImport_ImportModule("Blender.Material");
1301         if (mod) {
1302                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1303                 Py_DECREF(mod);
1304                 if (fcn) {
1305                         PyDict_SetItemString(d, "ma", fcn);
1306                         Py_DECREF(fcn);
1307                 }
1308         } else {
1309                 PyErr_Clear();
1310         }
1311
1312         return 0;
1313 }
1314
1315 /* error return function for BPY_eval_pydriver */
1316 static float pydriver_error(IpoDriver *driver) {
1317
1318         if (bpy_pydriver_oblist)
1319                 bpy_pydriver_freeList();
1320
1321         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
1322                 PyDict_Clear(bpy_pydriver_Dict);
1323                 Py_DECREF(bpy_pydriver_Dict);
1324                 bpy_pydriver_Dict = NULL;
1325         }
1326
1327         driver->flag |= IPO_DRIVER_FLAG_INVALID; /* py expression failed */
1328         
1329         if (driver->ob)
1330                 fprintf(stderr, "\nError in Ipo Driver: Object %s\nThis is the failed Python expression:\n'%s'\n\n", driver->ob->id.name+2, driver->name);
1331         else
1332                 fprintf(stderr, "\nError in Ipo Driver: No Object\nThis is the failed Python expression:\n'%s'\n\n", driver->name);
1333         
1334         PyErr_Print();
1335
1336         return 0.0f;
1337 }
1338
1339
1340 /********PyConstraints*********/
1341
1342 /* This function checks whether a text-buffer is a PyConstraint candidate.
1343  * It uses simple text parsing that could be easily confused!
1344  */
1345 int BPY_is_pyconstraint(Text *text)
1346 {
1347         TextLine *tline = text->lines.first;
1348
1349         if (tline && (tline->len > 10)) {
1350                 char *line = tline->line;
1351                 
1352                 /* Expected format: #BPYCONSTRAINT
1353                  * The actual checks are forgiving, so slight variations also work. */
1354                 if (line && line[0] == '#' && strstr(line, "BPYCONSTRAINT")) return 1;
1355         }
1356         return 0;
1357 }
1358
1359 /* This function frees links from pyconstraints to a given text-buffer.
1360  * Used when a text-buffer is unlinked!
1361  */
1362 void BPY_free_pyconstraint_links(Text *text)
1363 {
1364         Object *ob;
1365         bConstraint *con;
1366         short update;
1367         
1368         /*check all pyconstraints*/
1369         for (ob=G.main->object.first; ob; ob=ob->id.next) {
1370                 update = 0;
1371                 if(ob->type==OB_ARMATURE && ob->pose) {
1372                         bPoseChannel *pchan;
1373                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1374                                 for (con = pchan->constraints.first; con; con=con->next) {
1375                                         if (con->type==CONSTRAINT_TYPE_PYTHON) {
1376                                                 bPythonConstraint *data = con->data;
1377                                                 if (data->text==text) data->text = NULL;
1378                                                 update = 1;
1379                                                 
1380                                         }
1381                                 }
1382                         }
1383                 }
1384                 for (con = ob->constraints.first; con; con=con->next) {
1385                         if (con->type==CONSTRAINT_TYPE_PYTHON) {
1386                                 bPythonConstraint *data = con->data;
1387                                 if (data->text==text) data->text = NULL;
1388                                 update = 1;
1389                         }
1390                 }
1391                 
1392                 if (update) {
1393                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1394                 }
1395         }
1396 }
1397
1398 /* This function is called to update PyConstraint data so that it is compatible with the script. 
1399  * Some of the allocating/freeing of memory for constraint targets occurs here, espcially
1400  * if the number of targets changes.
1401  */
1402 void BPY_pyconstraint_update(Object *owner, bConstraint *con)
1403 {
1404         bPythonConstraint *data= con->data;
1405         
1406         if (data->text) {       
1407                 /* script does exist. it is assumed that this is a valid pyconstraint script */
1408                 PyObject *globals;
1409                 PyObject *retval, *gval;
1410                 PyGILState_STATE gilstate;
1411                 int num, i;
1412                 
1413                 /* clear the relevant flags first */
1414                 data->flag = 0;
1415
1416                 gilstate = PyGILState_Ensure();
1417
1418                 /* populate globals dictionary */
1419                 globals = CreateGlobalDictionary();
1420                 retval = RunPython(data->text, globals);
1421                 
1422                 if (retval == NULL) {
1423                         BPY_Err_Handle(data->text->id.name);
1424                         ReleaseGlobalDictionary(globals);
1425                         data->flag |= PYCON_SCRIPTERROR;
1426                         PyGILState_Release(gilstate);
1427                         return;
1428                 }
1429                 
1430                 Py_XDECREF(retval);
1431                 retval = NULL;
1432                 
1433                 /* try to find NUM_TARGETS */
1434                 gval = PyDict_GetItemString(globals, "NUM_TARGETS");
1435                 if ( (gval) && (num= PyInt_AsLong(gval)) ) {
1436                         /* NUM_TARGETS is defined... and non-zero */
1437                         bConstraintTarget *ct;
1438                         
1439                         /* check if it is valid (just make sure it is not negative)
1440                          *      TODO: PyInt_AsLong may return -1 as sign of invalid input... 
1441                          */
1442                         num = abs(num);
1443                         data->flag |= PYCON_USETARGETS;
1444                         
1445                         /* check if the number of targets has changed */
1446                         if (num < data->tarnum) {
1447                                 /* free a few targets */
1448                                 num= data->tarnum - num;
1449                                 for (i = 0; i < num; i++, data->tarnum--) {
1450                                         ct= data->targets.last;
1451                                         BLI_freelinkN(&data->targets, ct);
1452                                 }
1453                         }
1454                         else if (num > data->tarnum) {
1455                                 /* add a few targets */
1456                                 num = num - data->tarnum;
1457                                 for (i = 0; i < num; i++, data->tarnum++) {
1458                                         ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
1459                                         BLI_addtail(&data->targets, ct);
1460                                 }
1461                         }
1462                         
1463                         /* validate targets */
1464                         con->flag &= ~CONSTRAINT_DISABLE;
1465                         for (ct= data->targets.first; ct; ct= ct->next) {
1466                                 if (!exist_object(ct->tar)) {
1467                                         ct->tar = NULL;
1468                                         con->flag |= CONSTRAINT_DISABLE;
1469                                         break;
1470                                 }
1471                                 
1472                                 if ((ct->tar == owner) && (ct->subtarget[0] != 0)) {
1473                                         if (get_named_bone(get_armature(owner), ct->subtarget) == NULL) {
1474                                                 con->flag |= CONSTRAINT_DISABLE;
1475                                                 break;
1476                                         }
1477                                 }
1478                         }
1479                         
1480                         /* clear globals */
1481                         ReleaseGlobalDictionary(globals);
1482
1483                         PyGILState_Release(gilstate);
1484
1485                         return;
1486                 }
1487                 else {
1488                         /* NUM_TARGETS is not defined or equals 0 */
1489                         ReleaseGlobalDictionary(globals);
1490                         
1491                         /* free all targets */
1492                         BLI_freelistN(&data->targets);
1493                         data->tarnum = 0;
1494                         data->flag &= ~PYCON_USETARGETS;
1495                         
1496                         PyGILState_Release(gilstate);
1497
1498                         return;
1499                 }
1500         }
1501         else {
1502                 /* no script, so clear any settings/data now */
1503                 data->tarnum = 0;
1504                 data->flag = 0;
1505                 con->flag &= ~CONSTRAINT_DISABLE;
1506                 
1507                 BLI_freelistN(&data->targets);
1508                 
1509                 /* supposedly this should still leave the base struct... */
1510                 IDP_FreeProperty(data->prop);
1511         }
1512 }
1513
1514 /* PyConstraints Evaluation Function (only called from evaluate_constraint)
1515  * This function is responsible for modifying the ownermat that it is passed. 
1516  */
1517 void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase *targets)
1518 {
1519         PyObject *srcmat, *tarmat, *tarmats, *idprop;
1520         PyObject *globals;
1521         PyObject *gval;
1522         PyObject *pyargs, *retval;
1523         bConstraintTarget *ct;
1524         MatrixObject *retmat;
1525         int row, col, index;
1526         PyGILState_STATE gilstate;
1527
1528         if (!con->text) return;
1529         if (con->flag & PYCON_SCRIPTERROR) return;
1530
1531         gilstate = PyGILState_Ensure();
1532
1533         globals = CreateGlobalDictionary();
1534         
1535         /* wrap blender-data as PyObjects for evaluation 
1536          *      - we expose the owner's matrix as pymatrix
1537          *      - id-properties are wrapped using the id-properties pyapi
1538          *      - targets are presented as a list of matrices
1539          */
1540         srcmat = newMatrixObject((float *)cob->matrix, 4, 4, Py_NEW);
1541         idprop = BPy_Wrap_IDProperty(NULL, con->prop, NULL);
1542         
1543         tarmats= PyList_New(con->tarnum); 
1544         for (ct=targets->first, index=0; ct; ct=ct->next, index++) {
1545                 tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1546                 PyList_SET_ITEM(tarmats, index, tarmat);
1547         }
1548         
1549         if (!setup_armature_weakrefs()) {
1550                 fprintf(stderr, "Oops - weakref dict setup\n");
1551                 PyGILState_Release(gilstate);
1552
1553                 return;
1554         }
1555         
1556         retval = RunPython(con->text, globals);
1557         
1558         if (retval == NULL) {
1559                 BPY_Err_Handle(con->text->id.name);
1560                 con->flag |= PYCON_SCRIPTERROR;
1561                 
1562                 /* free temp objects */
1563                 Py_XDECREF(idprop);
1564                 Py_XDECREF(srcmat);
1565                 Py_XDECREF(tarmats);
1566                 
1567                 ReleaseGlobalDictionary(globals);
1568
1569                 PyGILState_Release(gilstate);
1570
1571                 return;
1572         }
1573
1574         if (retval) {Py_XDECREF( retval );}
1575         retval = NULL;
1576         
1577         gval = PyDict_GetItemString(globals, "doConstraint");
1578         if (!gval) {
1579                 printf("ERROR: no doConstraint function in constraint!\n");
1580                 
1581                 /* free temp objects */
1582                 Py_XDECREF(idprop);
1583                 Py_XDECREF(srcmat);
1584                 Py_XDECREF(tarmats);
1585                 
1586                 ReleaseGlobalDictionary(globals);
1587
1588                 PyGILState_Release(gilstate);
1589
1590                 return;
1591         }
1592         
1593         /* Now for the fun part! Try and find the functions we need. */
1594         if (PyFunction_Check(gval)) {
1595                 pyargs = Py_BuildValue("OOO", srcmat, tarmats, idprop);
1596                 retval = PyObject_CallObject(gval, pyargs);
1597                 Py_XDECREF(pyargs);
1598         } 
1599         else {
1600                 printf("ERROR: doConstraint is supposed to be a function!\n");
1601                 con->flag |= PYCON_SCRIPTERROR;
1602                 
1603                 Py_XDECREF(idprop);
1604                 Py_XDECREF(srcmat);
1605                 Py_XDECREF(tarmats);
1606                 
1607                 ReleaseGlobalDictionary(globals);
1608
1609                 PyGILState_Release(gilstate);
1610
1611                 return;
1612         }
1613         
1614         if (!retval) {
1615                 BPY_Err_Handle(con->text->id.name);
1616                 con->flag |= PYCON_SCRIPTERROR;
1617                 
1618                 /* free temp objects */
1619                 Py_XDECREF(idprop);
1620                 Py_XDECREF(srcmat);
1621                 Py_XDECREF(tarmats);
1622                 
1623                 ReleaseGlobalDictionary(globals);
1624
1625                 PyGILState_Release(gilstate);
1626
1627                 return;
1628         }
1629         
1630         
1631         if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1632                 printf("Error in PyConstraint - doConstraint: Function not returning a matrix!\n");
1633                 con->flag |= PYCON_SCRIPTERROR;
1634                 
1635                 Py_XDECREF(idprop);
1636                 Py_XDECREF(srcmat);
1637                 Py_XDECREF(tarmats);
1638                 Py_XDECREF(retval);
1639                 
1640                 ReleaseGlobalDictionary(globals);
1641
1642                 PyGILState_Release(gilstate);
1643
1644                 return;
1645         }
1646         
1647         retmat = (MatrixObject *)retval;
1648         if (retmat->rowSize != 4 || retmat->colSize != 4) {
1649                 printf("Error in PyConstraint - doConstraint: Matrix returned is the wrong size!\n");
1650                 con->flag |= PYCON_SCRIPTERROR;
1651                 
1652                 Py_XDECREF(idprop);
1653                 Py_XDECREF(srcmat);
1654                 Py_XDECREF(tarmats);
1655                 Py_XDECREF(retval);
1656                 
1657                 ReleaseGlobalDictionary(globals);
1658
1659                 PyGILState_Release(gilstate);
1660
1661                 return;
1662         }       
1663
1664         /* this is the reverse of code taken from newMatrix() */
1665         for(row = 0; row < 4; row++) {
1666                 for(col = 0; col < 4; col++) {
1667                         cob->matrix[row][col] = retmat->contigPtr[row*4+col];
1668                 }
1669         }
1670         
1671         /* free temp objects */
1672         Py_XDECREF(idprop);
1673         Py_XDECREF(srcmat);
1674         Py_XDECREF(tarmats);
1675         Py_XDECREF(retval);
1676         
1677         /* clear globals */
1678         ReleaseGlobalDictionary(globals);
1679
1680         PyGILState_Release(gilstate);
1681 }
1682
1683 /* This evaluates the target matrix for each target the PyConstraint uses.
1684  * NOTE: it only does one target at a time!
1685  */
1686 void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
1687 {
1688         PyObject *tar, *subtar;
1689         PyObject *tarmat, *idprop;
1690         PyObject *globals;
1691         PyObject *gval;
1692         PyObject *pyargs, *retval;
1693         MatrixObject *retmat;
1694         int row, col;
1695         PyGILState_STATE gilstate;
1696
1697         if (!con->text) return;
1698         if (con->flag & PYCON_SCRIPTERROR) return;
1699         if (!ct) return;
1700         
1701         gilstate = PyGILState_Ensure();
1702
1703         globals = CreateGlobalDictionary();
1704         
1705         tar = Object_CreatePyObject(ct->tar);
1706         if ((ct->tar) && (ct->tar->type==OB_ARMATURE)) {
1707                 bPoseChannel *pchan;
1708                 pchan = get_pose_channel(ct->tar->pose, ct->subtarget);
1709                 subtar = PyPoseBone_FromPosechannel(pchan);
1710         }
1711         else
1712                 subtar = PyString_FromString(ct->subtarget);
1713         
1714         tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1715         idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1716         
1717         if (!setup_armature_weakrefs()) {
1718                 fprintf(stderr, "Oops - weakref dict setup\n");
1719                 PyGILState_Release(gilstate);
1720                 return;
1721         }
1722         
1723         retval = RunPython(con->text, globals);
1724
1725         if (retval == NULL) {
1726                 BPY_Err_Handle(con->text->id.name);
1727                 con->flag |= PYCON_SCRIPTERROR;
1728                 
1729                 /* free temp objects */
1730                 Py_XDECREF(tar);
1731                 Py_XDECREF(subtar);
1732                 Py_XDECREF(idprop);
1733                 Py_XDECREF(tarmat);
1734                 
1735                 ReleaseGlobalDictionary(globals);
1736
1737                 PyGILState_Release(gilstate);
1738
1739                 return;
1740         }
1741
1742         Py_XDECREF(retval);
1743         retval = NULL;
1744         
1745         /* try to find doTarget function to set the target matrix */
1746         gval = PyDict_GetItemString(globals, "doTarget");
1747         if (!gval) {
1748                 /* free temp objects */
1749                 Py_XDECREF(tar);
1750                 Py_XDECREF(subtar);
1751                 Py_XDECREF(idprop);
1752                 Py_XDECREF(tarmat);
1753                 
1754                 ReleaseGlobalDictionary(globals);
1755
1756                 PyGILState_Release(gilstate);
1757
1758                 return;
1759         }
1760         
1761         /* Now for the fun part! Try and find the functions we need.*/
1762         if (PyFunction_Check(gval)) {
1763                 pyargs = Py_BuildValue("OOOO", tar, subtar, tarmat, idprop);
1764                 retval = PyObject_CallObject(gval, pyargs);
1765                 Py_XDECREF(pyargs);
1766         } 
1767         else {
1768                 printf("ERROR: doTarget is supposed to be a function!\n");
1769                 con->flag |= PYCON_SCRIPTERROR;
1770                 
1771                 Py_XDECREF(tar);
1772                 Py_XDECREF(subtar);
1773                 Py_XDECREF(idprop);
1774                 Py_XDECREF(tarmat);
1775                 
1776                 ReleaseGlobalDictionary(globals);
1777
1778                 PyGILState_Release(gilstate);
1779
1780                 return;
1781         }
1782         
1783         if (!retval) {
1784                 BPY_Err_Handle(con->text->id.name);
1785                 con->flag |= PYCON_SCRIPTERROR;
1786                 
1787                 
1788                 /* free temp objects */
1789                 Py_XDECREF(tar);
1790                 Py_XDECREF(subtar);
1791                 Py_XDECREF(idprop);
1792                 Py_XDECREF(tarmat);
1793                 
1794                 ReleaseGlobalDictionary(globals);
1795
1796                 PyGILState_Release(gilstate);
1797
1798                 return;
1799         }
1800         
1801         if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1802                 con->flag |= PYCON_SCRIPTERROR;
1803                 
1804                 Py_XDECREF(tar);
1805                 Py_XDECREF(subtar);
1806                 Py_XDECREF(idprop);
1807                 Py_XDECREF(tarmat);
1808                 Py_XDECREF(retval);
1809                 
1810                 ReleaseGlobalDictionary(globals);
1811
1812                 PyGILState_Release(gilstate);
1813
1814                 return;
1815         }
1816         
1817         retmat = (MatrixObject *)retval;
1818         if (retmat->rowSize != 4 || retmat->colSize != 4) {
1819                 printf("Error in PyConstraint - doTarget: Matrix returned is the wrong size!\n");
1820                 con->flag |= PYCON_SCRIPTERROR;
1821                 
1822                 Py_XDECREF(tar);
1823                 Py_XDECREF(subtar);
1824                 Py_XDECREF(idprop);
1825                 Py_XDECREF(tarmat);
1826                 Py_XDECREF(retval);
1827                 
1828                 ReleaseGlobalDictionary(globals);
1829
1830                 PyGILState_Release(gilstate);
1831
1832                 return;
1833         }       
1834
1835         /* this is the reverse of code taken from newMatrix() */
1836         for(row = 0; row < 4; row++) {
1837                 for(col = 0; col < 4; col++) {
1838                         ct->matrix[row][col] = retmat->contigPtr[row*4+col];
1839                 }
1840         }
1841         
1842         /* free temp objects */
1843         Py_XDECREF(tar);
1844         Py_XDECREF(subtar);
1845         Py_XDECREF(idprop);
1846         Py_XDECREF(tarmat);
1847         Py_XDECREF(retval);
1848         
1849         /* clear globals */
1850         ReleaseGlobalDictionary(globals);
1851
1852         PyGILState_Release(gilstate);
1853 }
1854
1855 /* This draws+handles the user-defined interface for editing pyconstraints idprops */
1856 void BPY_pyconstraint_settings(void *arg1, void *arg2)
1857 {
1858         bPythonConstraint *con= (bPythonConstraint *)arg1;
1859         PyObject *idprop;
1860         PyObject *globals;
1861         PyObject *gval;
1862         PyObject *retval;
1863         PyGILState_STATE gilstate;
1864         
1865         if (!con->text) return;
1866         if (con->flag & PYCON_SCRIPTERROR) return;
1867         
1868         gilstate = PyGILState_Ensure();
1869         
1870         globals = CreateGlobalDictionary();
1871         
1872         idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1873         
1874         retval = RunPython(con->text, globals);
1875
1876         if (retval == NULL) {
1877                 BPY_Err_Handle(con->text->id.name);
1878                 ReleaseGlobalDictionary(globals);
1879                 con->flag |= PYCON_SCRIPTERROR;
1880                 
1881                 /* free temp objects */
1882                 Py_XDECREF(idprop);
1883                 
1884                 PyGILState_Release(gilstate);
1885                 
1886                 return;
1887         }
1888
1889         if (retval) {Py_XDECREF( retval );}
1890         retval = NULL;
1891         
1892         gval = PyDict_GetItemString(globals, "getSettings");
1893         if (!gval) {
1894                 printf("ERROR: no getSettings function in constraint!\n");
1895                 
1896                 /* free temp objects */
1897                 ReleaseGlobalDictionary( globals );
1898                 Py_XDECREF(idprop);
1899
1900                 PyGILState_Release(gilstate);
1901
1902                 return;
1903         }
1904         
1905         /* Now for the fun part! Try and find the functions we need. */
1906         if (PyFunction_Check(gval)) {
1907                 retval = PyObject_CallFunction(gval, "O", idprop);
1908         } 
1909         else {
1910                 printf("ERROR: getSettings is supposed to be a function!\n");
1911                 ReleaseGlobalDictionary( globals );
1912                 
1913                 Py_XDECREF(idprop);
1914                 
1915                 PyGILState_Release(gilstate);
1916                 
1917                 return;
1918         }
1919         
1920         if (!retval) {
1921                 BPY_Err_Handle(con->text->id.name);
1922                 con->flag |= PYCON_SCRIPTERROR;
1923                 
1924                 /* free temp objects */
1925                 ReleaseGlobalDictionary(globals);
1926                 Py_XDECREF(idprop);
1927                 
1928                 PyGILState_Release(gilstate);
1929                 
1930                 return;
1931         }
1932         else {
1933                 /* clear globals */
1934                 ReleaseGlobalDictionary(globals);
1935                 
1936                 /* free temp objects */
1937                 Py_XDECREF(idprop);
1938                 Py_DECREF(retval);
1939                 
1940                 PyGILState_Release(gilstate);
1941                 
1942                 return;
1943         }
1944 }
1945
1946 /* Update function, it gets rid of pydrivers global dictionary, forcing
1947  * BPY_pydriver_eval to recreate it. This function is used to force
1948  * reloading the Blender text module "pydrivers.py", if available, so
1949  * updates in it reach pydriver evaluation. */
1950 void BPY_pydriver_update(void)
1951 {
1952         PyGILState_STATE gilstate = PyGILState_Ensure();
1953
1954         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
1955                 PyDict_Clear(bpy_pydriver_Dict);
1956                 Py_DECREF(bpy_pydriver_Dict);
1957                 bpy_pydriver_Dict = NULL;
1958         }
1959
1960         PyGILState_Release(gilstate);
1961
1962         return;
1963 }
1964
1965 /* for depsgraph.c, runs py expr once to collect all refs. made
1966  * to objects (self refs. to the object that owns the py driver
1967  * are not allowed). */
1968 struct Object **BPY_pydriver_get_objects(IpoDriver *driver)
1969 {
1970         /*if (!driver || !driver->ob || driver->name[0] == '\0')
1971                 return NULL;*/
1972
1973         /*PyErr_Clear();*/
1974
1975         /* clear the flag that marks invalid python expressions */
1976         driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
1977
1978         /* tell we're running a pydriver, so Get() functions know they need
1979          * to add the requested obj to our list */
1980         bpy_pydriver_running(1);
1981
1982         /* append driver owner object as the 1st ob in the list;
1983          * we put it there to make sure it is not itself referenced in
1984          * its pydriver expression */
1985         bpy_pydriver_appendToList(driver->ob);
1986
1987         /* this will append any other ob referenced in expr (driver->name)
1988          * or set the driver's error flag if driver's py expression fails */
1989         BPY_pydriver_eval(driver);
1990
1991         bpy_pydriver_running(0); /* ok, we're done */
1992
1993         return bpy_pydriver_obArrayFromList(); /* NULL if eval failed */
1994 }
1995
1996 /* This evals py driver expressions, 'expr' is a Python expression that
1997  * should evaluate to a float number, which is returned. */
1998 float BPY_pydriver_eval(IpoDriver *driver)
1999 {
2000         char *expr = NULL;
2001         PyObject *retval, *bpy_ob = NULL;
2002         float result = 0.0f; /* default return */
2003         int setitem_retval;
2004         PyGILState_STATE gilstate;
2005
2006         if (!driver ||  (G.f&G_DOSCRIPTLINKS)==0) return result;
2007
2008         expr = driver->name; /* the py expression to be evaluated */
2009         if (!expr || expr[0]=='\0') return result;
2010
2011         gilstate = PyGILState_Ensure();
2012
2013         if (!bpy_pydriver_Dict) {
2014                 if (bpy_pydriver_create_dict() != 0) {
2015                         fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
2016                         PyGILState_Release(gilstate);
2017                         return result;
2018                 }
2019         }
2020
2021         if (driver->ob)
2022                 bpy_ob = Object_CreatePyObject(driver->ob);
2023
2024         if (!bpy_ob) {
2025                 Py_INCREF(Py_None);
2026                 bpy_ob = Py_None;
2027         }
2028
2029         setitem_retval = EXPP_dict_set_item_str(bpy_pydriver_Dict, "self", bpy_ob);
2030
2031         if( !setup_armature_weakrefs()){
2032                 fprintf( stderr, "Oops - weakref dict setup\n");
2033                 PyGILState_Release(gilstate);
2034                 return result;
2035         }
2036
2037         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
2038                 bpy_pydriver_Dict);
2039
2040         if (retval == NULL) {
2041                 result = pydriver_error(driver);
2042                 PyGILState_Release(gilstate);
2043                 return result;
2044         }
2045
2046         result = ( float )PyFloat_AsDouble( retval );
2047         Py_DECREF(retval);
2048         
2049         if (result == -1 && PyErr_Occurred()) {
2050                 result = pydriver_error(driver);
2051                 PyGILState_Release(gilstate);
2052                 return result;
2053         }
2054
2055         /* remove 'self', since this dict is also used by py buttons */
2056         if (setitem_retval == 0) PyDict_DelItemString(bpy_pydriver_Dict, "self");
2057
2058         /* all fine, make sure the "invalid expression" flag is cleared */
2059         driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
2060
2061         PyGILState_Release(gilstate);
2062
2063         return result;
2064 }
2065
2066 /* Button Python Evaluation */
2067
2068 /* Python evaluation for gui buttons:
2069  *      users can write any valid Python expression (that evals to an int or float)
2070  *      inside Blender's gui number buttons and have them evaluated to their
2071  *      actual int or float value.
2072  *
2073  *      The global dict used for pydrivers is also used here, so all imported
2074  *      modules for pydrivers (including the pydrivers.py Blender text) are
2075  *      available for button py eval, too. */
2076
2077 static int bpy_button_eval_error(char *expr) {
2078
2079         if (bpy_pydriver_oblist)
2080                 bpy_pydriver_freeList();
2081
2082         if (bpy_pydriver_Dict) { /* free the persistent global dict */
2083                 /* it's the same dict used by pydrivers */
2084                 PyDict_Clear(bpy_pydriver_Dict);
2085                 Py_DECREF(bpy_pydriver_Dict);
2086                 bpy_pydriver_Dict = NULL;
2087         }
2088
2089         fprintf(stderr, "\nError in button evaluation:\nThis is the failed Python expression:\n'%s'\n\n", expr);
2090
2091         PyErr_Print();
2092
2093         return -1;
2094 }
2095
2096 int BPY_button_eval(char *expr, double *value)
2097 {
2098         PyObject *retval, *floatval;
2099         PyGILState_STATE gilstate;
2100         int ret;
2101
2102         if (!value || !expr || expr[0]=='\0') return -1;
2103
2104         *value = 0.0; /* default value */
2105
2106         gilstate = PyGILState_Ensure();
2107
2108         if (!bpy_pydriver_Dict) {
2109                 if (bpy_pydriver_create_dict() != 0) {
2110                         fprintf(stderr,
2111                                 "Button Python Eval error: couldn't create Python dictionary \n");
2112                         PyGILState_Release(gilstate);
2113                         return -1;
2114                 }
2115         }
2116
2117
2118         if( !setup_armature_weakrefs()){
2119                 fprintf(stderr, "Oops - weakref dict\n");
2120                 PyGILState_Release(gilstate);
2121                 return -1;
2122         }
2123
2124         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
2125                 bpy_pydriver_Dict);
2126
2127         if (retval == NULL) {
2128                 ret = bpy_button_eval_error(expr);
2129                 PyGILState_Release(gilstate);
2130                 return ret;
2131         }
2132         else {
2133                 floatval = PyNumber_Float(retval);
2134                 Py_DECREF(retval);
2135         }
2136
2137         if (floatval == NULL) {
2138                 ret = bpy_button_eval_error(expr);
2139                 PyGILState_Release(gilstate);
2140                 return ret;
2141         } else {
2142                 *value = (float)PyFloat_AsDouble(floatval);
2143                 Py_DECREF(floatval);
2144         }
2145
2146         PyGILState_Release(gilstate);
2147
2148         return 0; /* successful exit */
2149 }
2150
2151
2152 /*****************************************************************************/
2153 /* ScriptLinks                                                        */
2154 /*****************************************************************************/
2155
2156 /*****************************************************************************/
2157 /* Description:                                                          */
2158 /* Notes:                               Not implemented yet      */
2159 /*****************************************************************************/
2160 void BPY_clear_bad_scriptlinks( struct Text *byebye )
2161 {
2162 /*
2163         BPY_clear_bad_scriptlist(getObjectList(), byebye);
2164         BPY_clear_bad_scriptlist(getLampList(), byebye);
2165         BPY_clear_bad_scriptlist(getCameraList(), byebye);
2166         BPY_clear_bad_scriptlist(getMaterialList(), byebye);
2167         BPY_clear_bad_scriptlist(getWorldList(),        byebye);
2168         BPY_clear_bad_scriptlink(&scene_getCurrent()->id, byebye);
2169
2170         allqueue(REDRAWBUTSSCRIPT, 0);
2171 */
2172         return;
2173 }
2174
2175 /*****************************************************************************
2176 * Description: Loop through all scripts of a list of object types, and 
2177 *       execute these scripts.  
2178 *       For the scene, only the current active scene the scripts are 
2179 *       executed (if any).
2180 *****************************************************************************/
2181 void BPY_do_all_scripts( short event, short anim )
2182 {
2183         /* during stills rendering we disable FRAMECHANGED events */
2184         static char disable_frame_changed = 0;
2185
2186         if ((event == SCRIPT_FRAMECHANGED) && disable_frame_changed)
2187                 return;
2188
2189         DoAllScriptsFromList( &( G.main->object ), event );
2190         DoAllScriptsFromList( &( G.main->lamp ), event );
2191         DoAllScriptsFromList( &( G.main->camera ), event );
2192         DoAllScriptsFromList( &( G.main->mat ), event );
2193         DoAllScriptsFromList( &( G.main->world ), event );
2194
2195         BPY_do_pyscript( &( G.scene->id ), event );
2196
2197         /* Don't allow the Python Interpreter to release the GIL on
2198          * its own, to guarantee PyNodes work properly. For Blender this
2199          * is currently the best default behavior.
2200          * The following code in C is equivalent in Python to:
2201          * "import sys; sys.setcheckinterval(sys.maxint)" */
2202         if (event == SCRIPT_RENDER) {
2203                 _Py_CheckInterval = PyInt_GetMax();
2204                 if (!anim)
2205                         disable_frame_changed = 1;
2206         }
2207         else if (event == SCRIPT_POSTRENDER) {
2208                 _Py_CheckInterval = 100; /* Python default */
2209                 disable_frame_changed = 0;
2210         }
2211
2212         return;
2213 }
2214
2215 /*****************************************************************************
2216 * Description: Execute a Python script when an event occurs. The following  
2217 *               events are possible: frame changed, load script and redraw.  
2218 *               Only events happening to one of the following object types   
2219 *               are handled: Object, Lamp, Camera, Material, World and      
2220 *               Scene.                  
2221 *****************************************************************************/
2222
2223 static ScriptLink *ID_getScriptlink( ID * id )
2224 {
2225         switch ( MAKE_ID2( id->name[0], id->name[1] ) ) {
2226         case ID_OB:
2227                 return &( ( Object * ) id )->scriptlink;
2228         case ID_LA:
2229                 return &( ( Lamp * ) id )->scriptlink;
2230         case ID_CA:
2231                 return &( ( Camera * ) id )->scriptlink;
2232         case ID_MA:
2233                 return &( ( Material * ) id )->scriptlink;
2234         case ID_WO:
2235                 return &( ( World * ) id )->scriptlink;
2236         case ID_SCE:
2237                 return &( ( Scene * ) id )->scriptlink;
2238         default:
2239                 return NULL;
2240         }
2241 }
2242
2243 int BPY_has_onload_script( void )
2244 {
2245         ScriptLink *slink = &G.scene->scriptlink;
2246         int i;
2247
2248         if( !slink || !slink->totscript )
2249                 return 0;
2250
2251         for( i = 0; i < slink->totscript; i++ ) {
2252                 if( ( slink->flag[i] == SCRIPT_ONLOAD )
2253                     && ( slink->scripts[i] != NULL ) )
2254                         return 1;
2255         }
2256
2257         return 0;
2258 }
2259
2260 void BPY_do_pyscript( ID * id, short event )
2261 {
2262         ScriptLink *scriptlink;
2263
2264         if( !id ) return;
2265
2266         scriptlink = ID_getScriptlink( id );
2267
2268         if( scriptlink && scriptlink->totscript ) {
2269                 PyObject *value;
2270                 PyObject *dict;
2271                 PyObject *ret;
2272                 int index, during_slink = during_scriptlink(  );
2273                 PyGILState_STATE gilstate;
2274
2275                 /* invalid scriptlinks (new .blend was just loaded), return */
2276                 if( during_slink < 0 )
2277                         return;
2278
2279                 gilstate = PyGILState_Ensure();
2280
2281                 if( !setup_armature_weakrefs()){
2282                         printf("Oops - weakref dict, this is a bug\n");
2283                         PyGILState_Release(gilstate);
2284                         return;
2285                 }
2286                 
2287                 value = GetPyObjectFromID( id );
2288                 if( !value){
2289                         printf("Oops - could not get a valid python object for Blender.link, this is a bug\n");
2290                         PyGILState_Release(gilstate);
2291                         return;
2292                 }
2293                 
2294                 /* tell we're running a scriptlink.  The sum also tells if this
2295                  * script is running nested inside another.  Blender.Load needs
2296                  * this info to avoid trouble with invalid slink pointers. */
2297                 during_slink++;
2298                 disable_where_scriptlink( (short)during_slink );
2299
2300                 /* set globals in Blender module to identify scriptlink */
2301                 PyDict_SetItemString(   g_blenderdict, "bylink", Py_True);
2302                 EXPP_dict_set_item_str( g_blenderdict, "link", value );
2303                 EXPP_dict_set_item_str( g_blenderdict, "event",
2304                                       PyString_FromString( event_to_name
2305                                                            ( event ) ) );
2306                 if (event == SCRIPT_POSTRENDER) event = SCRIPT_RENDER;
2307
2308                 for( index = 0; index < scriptlink->totscript; index++ ) {
2309                         if( ( scriptlink->flag[index] == event ) &&
2310                             ( scriptlink->scripts[index] != NULL ) ) {
2311                                 dict = CreateGlobalDictionary(  );
2312                                 ret = RunPython( ( Text * ) scriptlink->
2313                                                  scripts[index], dict );
2314                                 ReleaseGlobalDictionary( dict );
2315
2316                                 if( !ret ) {
2317                                         /* Failed execution of the script */
2318                                         BPY_Err_Handle( scriptlink->
2319                                                         scripts[index]->name +
2320                                                         2 );
2321                                         //BPY_end_python ();
2322                                         //BPY_start_python ();
2323                                 } else {
2324                                         Py_DECREF( ret );
2325                                 }
2326                                 /* If a scriptlink has just loaded a new .blend file, the
2327                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
2328                                  * so we stop here. */
2329                                 if( during_scriptlink(  ) == -1 ) {
2330                                         during_slink = 1;
2331                                         break;
2332                                 }
2333                         }
2334                 }
2335
2336                 disable_where_scriptlink( (short)(during_slink - 1) );
2337
2338                 /* cleanup bylink flag and clear link so PyObject
2339                  * can be released 
2340                  */
2341                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
2342                 PyDict_SetItemString( g_blenderdict, "link", Py_None );
2343                 EXPP_dict_set_item_str( g_blenderdict, "event", PyString_FromString( "" ) );
2344
2345                 PyGILState_Release(gilstate);
2346         }
2347 }
2348
2349
2350 /* SPACE HANDLERS */
2351
2352 /* These are special script links that can be assigned to ScrArea's to
2353  * (EVENT type) receive events sent to a given space (and use or ignore them) or
2354  * (DRAW type) be called after the space is drawn, to draw anything on top of
2355  * the space area. */
2356
2357 /* How to add space handlers to other spaces:
2358  * - add the space event defines to DNA_scriptlink_types.h, as done for
2359  *   3d view: SPACEHANDLER_VIEW3D_EVENT, for example;
2360  * - add the new defines to Blender.SpaceHandler dictionary in Blender.c;
2361  * - check space.c for how to call the event handlers;
2362  * - check drawview.c for how to call the draw handlers;
2363  * - check header_view3d.c for how to add the "Space Handler Scripts" menu.
2364  * Note: DRAW handlers should be called with 'event = 0', chech drawview.c */
2365
2366 int BPY_has_spacehandler(Text *text, ScrArea *sa)
2367 {
2368         ScriptLink *slink;
2369         int index;
2370
2371         if (!sa || !text) return 0;
2372
2373         slink = &sa->scriptlink;
2374
2375         for (index = 0; index < slink->totscript; index++) {
2376                 if (slink->scripts[index] && (slink->scripts[index] == (ID *)text))
2377                         return 1;
2378         }
2379
2380         return 0;       
2381 }
2382
2383 int BPY_is_spacehandler(Text *text, char spacetype)
2384 {
2385         TextLine *tline = text->lines.first;
2386         unsigned short type = 0;
2387
2388         if (tline && (tline->len > 10)) {
2389                 char *line = tline->line;
2390
2391                 /* Expected format: # SPACEHANDLER.SPACE.TYPE
2392                  * Ex: # SPACEHANDLER.VIEW3D.DRAW
2393                  * The actual checks are forgiving, so slight variations also work. */
2394                 if (line && line[0] == '#' && strstr(line, "HANDLER")) {
2395                         line++; /* skip '#' */
2396
2397                         /* only done for 3D View right now, trivial to add for others: */
2398                         switch (spacetype) {
2399                                 case SPACE_VIEW3D:
2400                                         if (strstr(line, "3D")) { /* VIEW3D, 3DVIEW */
2401                                                 if (strstr(line, "DRAW")) type = SPACEHANDLER_VIEW3D_DRAW;
2402                                                 else if (strstr(line, "EVENT")) type = SPACEHANDLER_VIEW3D_EVENT;
2403                                         }
2404                                         break;
2405                         }
2406                 }
2407         }
2408         return type; /* 0 if not a space handler */
2409 }
2410
2411 int BPY_del_spacehandler(Text *text, ScrArea *sa)
2412 {
2413         ScriptLink *slink;
2414         int i, j;
2415
2416         if (!sa || !text) return -1;
2417
2418         slink = &sa->scriptlink;
2419         if (slink->totscript < 1) return -1;
2420
2421         for (i = 0; i < slink->totscript; i++) {
2422                 if (text == (Text *)slink->scripts[i]) {
2423
2424                         for (j = i; j < slink->totscript - 1; j++) {
2425                                 slink->flag[j] = slink->flag[j+1];
2426                                 slink->scripts[j] = slink->scripts[j+1];
2427                         }
2428                         slink->totscript--;
2429                         /* like done in buttons_script.c we just free memory
2430                          * if all slinks have been removed -- less fragmentation,
2431                          * these should be quite small arrays */
2432                         if (slink->totscript == 0) {
2433                                 if (slink->scripts) MEM_freeN(slink->scripts);
2434                                 if (slink->flag) MEM_freeN(slink->flag);
2435                                 break;
2436                         }
2437                 }
2438         }
2439         return 0;
2440 }
2441
2442 int BPY_add_spacehandler(Text *text, ScrArea *sa, char spacetype)
2443 {
2444         unsigned short handlertype;
2445
2446         if (!sa || !text) return -1;
2447
2448         handlertype = (unsigned short)BPY_is_spacehandler(text, spacetype);
2449
2450         if (handlertype) {
2451                 ScriptLink *slink = &sa->scriptlink;
2452                 void *stmp, *ftmp;
2453                 unsigned short space_event = SPACEHANDLER_VIEW3D_EVENT;
2454
2455                 /* extend slink */
2456
2457                 stmp= slink->scripts;           
2458                 slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1),
2459                         "spacehandlerscripts");
2460         
2461                 ftmp= slink->flag;              
2462                 slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1),
2463                         "spacehandlerflags");
2464         
2465                 if (slink->totscript) {
2466                         memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript));
2467                         MEM_freeN(stmp);
2468
2469                         memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript));
2470                         MEM_freeN(ftmp);
2471                 }
2472
2473                 switch (spacetype) {
2474                         case SPACE_VIEW3D:
2475                                 if (handlertype == 1) space_event = SPACEHANDLER_VIEW3D_EVENT;
2476                                 else space_event = SPACEHANDLER_VIEW3D_DRAW;
2477                                 break;
2478                         default:
2479                                 break;
2480                 }
2481
2482                 slink->scripts[slink->totscript] = (ID *)text;
2483                 slink->flag[slink->totscript]= space_event;
2484
2485                 slink->totscript++;
2486                 slink->actscript = slink->totscript;
2487
2488         }
2489         return 0;
2490 }
2491
2492 int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
2493         short eventValue, unsigned short space_event )
2494 {
2495         ScriptLink *scriptlink;
2496         int retval = 0;
2497         PyGILState_STATE gilstate;
2498         
2499         if (!sa || !(G.f & G_DOSCRIPTLINKS)) return 0;
2500         
2501         scriptlink = &sa->scriptlink;
2502
2503         if (scriptlink->totscript > 0) {
2504                 PyObject *dict;
2505                 PyObject *ret;
2506                 int index, during_slink = during_scriptlink();
2507
2508                 /* invalid scriptlinks (new .blend was just loaded), return */
2509                 if (during_slink < 0) return 0;
2510
2511                 /* tell we're running a scriptlink.  The sum also tells if this script
2512                  * is running nested inside another.  Blender.Load needs this info to
2513                  * avoid trouble with invalid slink pointers.
2514                  * Update (test): allow EVENT space handlers to call file/image selectors,
2515                  * still disabled for DRAW space handlers: */
2516                 if (event == 0) { /* event = 0: DRAW space handler */
2517                         during_slink++;
2518                         disable_where_scriptlink( (short)during_slink );
2519                 }
2520                 
2521                 gilstate = PyGILState_Ensure();
2522                 
2523                 if( !setup_armature_weakrefs()){
2524                         printf("Oops - weakref dict, this is a bug\n");
2525                         PyGILState_Release(gilstate);
2526                         return 0;
2527                 }
2528                 
2529                 /* set globals in Blender module to identify space handler scriptlink */
2530                 PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
2531                 /* unlike normal scriptlinks, here Blender.link is int (space event type) */
2532                 EXPP_dict_set_item_str(g_blenderdict, "link", PyInt_FromLong(space_event));
2533                 /* note: DRAW space_events set event and val to 0 */
2534                 EXPP_dict_set_item_str(g_blenderdict, "event", PyInt_FromLong(event));
2535                 EXPP_dict_set_item_str(g_blenderdict, "eventValue", PyInt_FromLong(eventValue));
2536                 /* now run all assigned space handlers for this space and space_event */
2537                 for( index = 0; index < scriptlink->totscript; index++ ) {
2538                         
2539                         /* for DRAW handlers: */
2540                         if (event == 0) {
2541                                 glPushAttrib(GL_ALL_ATTRIB_BITS);
2542                                 glMatrixMode(GL_PROJECTION);
2543                                 glPushMatrix();
2544                                 glMatrixMode(GL_MODELVIEW);
2545                                 glPushMatrix();
2546                         }
2547                         
2548                         if( ( scriptlink->flag[index] == space_event ) &&
2549                             ( scriptlink->scripts[index] != NULL ) ) {
2550                                 dict = CreateGlobalDictionary();
2551                                 ret = RunPython( ( Text * ) scriptlink->scripts[index], dict );
2552                                 ReleaseGlobalDictionary( dict );
2553
2554                                 if (!ret) { /* Failed execution of the script */
2555                                         BPY_Err_Handle( scriptlink->scripts[index]->name+2 );
2556                                 } else {
2557                                         Py_DECREF(ret);
2558
2559                                         /* an EVENT type (event != 0) script can either accept an event or
2560                                          * ignore it:
2561                                          * if the script sets Blender.event to None it accepted it;
2562                                          * otherwise the space's event handling callback that called us
2563                                          * can go on processing the event */
2564                                         if (event && (PyDict_GetItemString(g_blenderdict,"event") == Py_None))
2565                                                 retval = 1; /* event was swallowed */
2566                                 }
2567                                 
2568                                 /* If a scriptlink has just loaded a new .blend file, the
2569                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
2570                                  * so we stop here. */
2571                                 if( during_scriptlink(  ) == -1 ) {
2572                                         during_slink = 1;
2573                                         if (event == 0) glPopAttrib();
2574                                         break;
2575                                 }
2576                         }
2577                         
2578                         /* for DRAW handlers: */
2579                         if (event == 0) {
2580                                 glMatrixMode(GL_PROJECTION);
2581                                 glPopMatrix();
2582                                 glMatrixMode(GL_MODELVIEW);
2583                                 glPopMatrix();
2584                                 glPopAttrib();
2585                                 disable_where_scriptlink( (short)(during_slink - 1) );
2586                         }
2587                 
2588                 }
2589                 
2590                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
2591                 PyDict_SetItemString(g_blenderdict, "link", Py_None );
2592                 EXPP_dict_set_item_str(g_blenderdict, "event", PyString_FromString(""));
2593                 
2594                 PyGILState_Release(gilstate);
2595         }
2596         
2597         /* retval:
2598          * space_event is of type EVENT:
2599          * 0 - event was returned,
2600          * 1 - event was processed;
2601          * space_event is of type DRAW:
2602          * 0 always */
2603
2604         return retval;
2605 }
2606
2607 /*****************************************************************************
2608 * Description:  
2609 * Notes:
2610 *****************************************************************************/
2611 void BPY_free_scriptlink( struct ScriptLink *slink )
2612 {
2613         if( slink->totscript ) {
2614                 if( slink->flag ) {
2615                         MEM_freeN( slink->flag );
2616                         slink->flag= NULL;
2617                 }
2618                 if( slink->scripts ) {
2619                         MEM_freeN( slink->scripts );
2620                         slink->scripts= NULL;
2621                 }
2622         }
2623
2624         return;
2625 }
2626
2627 static int CheckAllSpaceHandlers(Text *text)
2628 {
2629         bScreen *screen;
2630         ScrArea *sa;
2631         ScriptLink *slink;
2632         int fixed = 0;
2633
2634         for (screen = G.main->screen.first; screen; screen = screen->id.next) {
2635                 for (sa = screen->areabase.first; sa; sa = sa->next) {
2636                         slink = &sa->scriptlink;
2637                         if (!slink->totscript) continue;
2638                         if (BPY_del_spacehandler(text, sa) == 0) fixed++;
2639                 }
2640         }
2641         return fixed;
2642 }
2643
2644 static int CheckAllScriptsFromList( ListBase * list, Text * text )
2645 {
2646         ID *id;
2647         ScriptLink *scriptlink;
2648         int index;
2649         int fixed = 0;
2650
2651         id = list->first;
2652
2653         while( id != NULL ) {
2654                 scriptlink = ID_getScriptlink( id );
2655                 if( scriptlink && scriptlink->totscript ) {
2656                         for( index = 0; index < scriptlink->totscript; index++) {
2657                                 if ((Text *)scriptlink->scripts[index] == text) {
2658                                         scriptlink->scripts[index] = NULL;
2659                                         fixed++;
2660                                 }
2661                         }
2662                 }
2663                 id = id->next;
2664         }
2665
2666         return fixed;
2667 }
2668
2669 /* When a Text is deleted, we need to unlink it from eventual scriptlinks */
2670 int BPY_check_all_scriptlinks( Text * text )
2671 {
2672         int fixed = 0;
2673         fixed += CheckAllScriptsFromList( &( G.main->object ), text );
2674         fixed += CheckAllScriptsFromList( &( G.main->lamp ), text );
2675         fixed += CheckAllScriptsFromList( &( G.main->camera ), text );
2676         fixed += CheckAllScriptsFromList( &( G.main->mat ), text );
2677         fixed += CheckAllScriptsFromList( &( G.main->world ), text );
2678         fixed += CheckAllScriptsFromList( &( G.main->scene ), text );
2679         fixed += CheckAllSpaceHandlers(text);
2680
2681         return fixed;
2682 }
2683
2684 /*****************************************************************************
2685 * Description: 
2686 * Notes:
2687 *****************************************************************************/
2688 void BPY_copy_scriptlink( struct ScriptLink *scriptlink )
2689 {
2690         void *tmp;
2691
2692         if( scriptlink->totscript ) {
2693
2694                 tmp = scriptlink->scripts;
2695                 scriptlink->scripts =
2696                         MEM_mallocN( sizeof( ID * ) * scriptlink->totscript,
2697                                      "scriptlistL" );
2698                 memcpy( scriptlink->scripts, tmp,
2699                         sizeof( ID * ) * scriptlink->totscript );
2700
2701                 tmp = scriptlink->flag;
2702                 scriptlink->flag =
2703                         MEM_mallocN( sizeof( short ) * scriptlink->totscript,
2704                                      "scriptlistF" );
2705                 memcpy( scriptlink->flag, tmp,
2706                         sizeof( short ) * scriptlink->totscript );
2707         }
2708
2709         return;
2710 }
2711
2712 /****************************************************************************
2713 * Description:
2714 * Notes:                Not implemented yet
2715 *****************************************************************************/
2716 int BPY_call_importloader( char *name )
2717 {                       /* XXX Should this function go away from Blender? */
2718         printf( "In BPY_call_importloader(name=%s)\n", name );
2719         return ( 0 );
2720 }
2721
2722 /*****************************************************************************
2723 * Private functions
2724 *****************************************************************************/
2725
2726 /*****************************************************************************
2727 * Description: This function executes the python script passed by text. 
2728 *               The Python dictionary containing global variables needs to
2729 *               be passed in globaldict.
2730 *****************************************************************************/
2731 static PyObject *RunPython( Text * text, PyObject * globaldict )
2732 {
2733         char *buf = NULL;
2734
2735 /* The script text is compiled to Python bytecode and saved at text->compiled
2736  * to speed-up execution if the user executes the script multiple times */
2737
2738         if( !text->compiled ) { /* if it wasn't already compiled, do it now */
2739                 buf = txt_to_buf( text );
2740
2741                 text->compiled =
2742                         Py_CompileString( buf, text->id.name+2, Py_file_input );
2743
2744                 MEM_freeN( buf );
2745
2746                 if( PyErr_Occurred(  ) ) {
2747                         BPY_free_compiled_text( text );
2748                         return NULL;
2749                 }
2750
2751         }
2752
2753         return PyEval_EvalCode( text->compiled, globaldict, globaldict );
2754 }
2755
2756 /*****************************************************************************
2757 * Description: This function creates a new Python dictionary object.
2758 *****************************************************************************/
2759 static PyObject *CreateGlobalDictionary( void )
2760 {
2761         PyObject *dict = PyDict_New(  );
2762
2763         PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
2764         EXPP_dict_set_item_str( dict, "__name__",
2765                               PyString_FromString( "__main__" ) );
2766
2767         return dict;
2768 }
2769
2770 /*****************************************************************************
2771 * Description: This function deletes a given Python dictionary object.
2772 *****************************************************************************/
2773 static void ReleaseGlobalDictionary( PyObject * dict )
2774 {
2775         PyDict_Clear( dict );
2776         Py_DECREF( dict );      /* Release dictionary. */
2777
2778         return;
2779 }
2780
2781 /***************************************************************************
2782 * Description: This function runs all scripts (if any) present in the
2783 *               list argument. The event by which the function has been 
2784 *               called, is passed in the event argument.
2785 *****************************************************************************/
2786 static void DoAllScriptsFromList( ListBase * list, short event )
2787 {
2788         ID *id;
2789
2790         id = list->first;
2791
2792         while( id != NULL ) {
2793                 BPY_do_pyscript( id, event );
2794                 id = id->next;
2795         }
2796
2797         return;
2798 }
2799
2800 static PyObject *importText( char *name )
2801 {
2802         Text *text;
2803         char txtname[22]; /* 21+NULL */
2804         char *buf = NULL;
2805         int namelen = strlen( name );
2806         
2807         if (namelen>21-3) return NULL; /* we know this cant be importable, the name is too long for blender! */
2808         
2809         memcpy( txtname, name, namelen );
2810         memcpy( &txtname[namelen], ".py", 4 );
2811
2812         for(text = G.main->text.first; text; text = text->id.next) {
2813                 if( !strcmp( txtname, text->id.name+2 ) )
2814                         break;
2815         }
2816
2817         if( !text )
2818                 return NULL;
2819
2820         if( !text->compiled ) {
2821                 buf = txt_to_buf( text );
2822                 text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
2823                 MEM_freeN( buf );
2824
2825                 if( PyErr_Occurred(  ) ) {
2826                         PyErr_Print(  );
2827                         BPY_free_compiled_text( text );
2828                         return NULL;
2829                 }
2830         }
2831
2832         return PyImport_ExecCodeModule( name, text->compiled );
2833 }
2834
2835 static PyMethodDef bimport[] = {
2836         {"blimport", blender_import, METH_VARARGS, "our own import"}
2837 };
2838
2839 static PyObject *blender_import( PyObject * self, PyObject * args )
2840 {
2841         PyObject *exception, *err, *tb;
2842         char *name;
2843         PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
2844         PyObject *m;
2845         //PyObject_Print(args, stderr, 0);
2846 #if (PY_VERSION_HEX >= 0x02060000)
2847         int dummy_val; /* what does this do?*/
2848         
2849         if( !PyArg_ParseTuple( args, "s|OOOi:bimport",
2850                                &name, &globals, &locals, &fromlist, &dummy_val) )
2851                 return NULL;
2852 #else
2853         if( !PyArg_ParseTuple( args, "s|OOO:bimport",
2854                                &name, &globals, &locals, &fromlist ) )
2855                 return NULL;
2856 #endif
2857         m = PyImport_ImportModuleEx( name, globals, locals, fromlist );
2858
2859         if( m )
2860                 return m;
2861         else
2862                 PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
2863
2864         m = importText( name );
2865         if( m ) {               /* found module, ignore above exception */
2866                 PyErr_Clear(  );
2867                 Py_XDECREF( exception );
2868                 Py_XDECREF( err );
2869                 Py_XDECREF( tb );
2870                 printf( "imported from text buffer...\n" );
2871         } else {
2872                 PyErr_Restore( exception, err, tb );
2873         }
2874         return m;
2875 }
2876
2877 static void init_ourImport( void )
2878 {
2879         PyObject *m, *d;
2880         PyObject *import = PyCFunction_New( bimport, NULL );
2881
2882         m = PyImport_AddModule( "__builtin__" );
2883         d = PyModule_GetDict( m );
2884         
2885         EXPP_dict_set_item_str( d, "__import__", import );
2886 }
2887
2888 /*
2889  * find in-memory module and recompile
2890  */
2891
2892 static PyObject *reimportText( PyObject *module )
2893 {
2894         Text *text;
2895         char *txtname;
2896         char *name;
2897         char *buf = NULL;
2898
2899         /* get name, filename from the module itself */
2900
2901         txtname = PyModule_GetFilename( module );
2902         name = PyModule_GetName( module );
2903         if( !txtname || !name)
2904                 return NULL;
2905
2906         /* look up the text object */
2907         text = ( Text * ) & ( G.main->text.first );
2908         while( text ) {
2909                 if( !strcmp( txtname, text->id.name+2 ) )
2910                         break;
2911                 text = text->id.next;
2912         }
2913
2914         /* uh-oh.... didn't find it */
2915         if( !text )
2916                 return NULL;
2917
2918         /* if previously compiled, free the object */
2919         /* (can't see how could be NULL, but check just in case) */ 
2920         if( text->compiled ){
2921                 Py_DECREF( (PyObject *)text->compiled );
2922         }
2923
2924         /* compile the buffer */
2925         buf = txt_to_buf( text );
2926         text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
2927         MEM_freeN( buf );
2928
2929         /* if compile failed.... return this error */
2930         if( PyErr_Occurred(  ) ) {
2931                 PyErr_Print(  );
2932                 BPY_free_compiled_text( text );
2933                 return NULL;
2934         }
2935
2936         /* make into a module */
2937         return PyImport_ExecCodeModule( name, text->compiled );
2938 }
2939
2940 /*
2941  * our reload() module, to handle reloading in-memory scripts
2942  */
2943
2944 static PyObject *blender_reload( PyObject * self, PyObject * args )
2945 {
2946         PyObject *exception, *err, *tb;
2947         PyObject *module = NULL;
2948         PyObject *newmodule = NULL;
2949
2950         /* check for a module arg */
2951         if( !PyArg_ParseTuple( args, "O:breload", &module ) )
2952                 return NULL;
2953
2954         /* try reimporting from file */
2955         newmodule = PyImport_ReloadModule( module );
2956         if( newmodule )
2957                 return newmodule;
2958
2959         /* no file, try importing from memory */
2960         PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
2961
2962         newmodule = reimportText( module );
2963         if( newmodule ) {               /* found module, ignore above exception */
2964                 PyErr_Clear(  );
2965                 Py_XDECREF( exception );
2966                 Py_XDECREF( err );
2967                 Py_XDECREF( tb );
2968         } else
2969                 PyErr_Restore( exception, err, tb );
2970
2971         return newmodule;
2972 }
2973
2974 static PyMethodDef breload[] = {
2975         {"blreload", blender_reload, METH_VARARGS, "our own reload"}
2976 };
2977
2978 static void init_ourReload( void )
2979 {
2980         PyObject *m, *d;
2981         PyObject *reload = PyCFunction_New( breload, NULL );
2982
2983         m = PyImport_AddModule( "__builtin__" );
2984         d = PyModule_GetDict( m );
2985         EXPP_dict_set_item_str( d, "reload", reload );
2986 }
2987
2988
2989 void BPY_scripts_clear_pyobjects( void )
2990 {
2991         Script *script;
2992         for (script=G.main->script.first; script; script=script->id.next) {
2993                 Py_XDECREF((PyObject *)script->py_draw);
2994                 Py_XDECREF((PyObject *)script->py_event);
2995                 Py_XDECREF((PyObject *)script->py_button);
2996                 Py_XDECREF((PyObject *)script->py_browsercallback);
2997                 Py_XDECREF((PyObject *)script->py_globaldict); 
2998                 SCRIPT_SET_NULL(script)
2999         }
3000 }
3001 void error_pyscript( void )
3002 {
3003         error("Python script error: check console");
3004 }