fix for [#17878] Scripts operating on blender objects don't clear memory after a...
[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         /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
621          * their user count. Not to mention holding references to wrapped data.
622          * This is especially bad when the PyObject for the wrapped data is free'd, after blender 
623          * has alredy dealocated the pointer */
624         PySys_SetObject( "last_traceback", Py_None);
625         return;
626 }
627
628 /****************************************************************************
629 * Description: This function executes the script passed by st.          
630 * Notes:        It is called by blender/src/drawtext.c when a Blender user  
631 *               presses ALT+PKEY in the script's text window. 
632 *****************************************************************************/
633 int BPY_txt_do_python_Text( struct Text *text )
634 {
635         PyObject *py_dict, *py_result;
636         BPy_constant *info;
637         char textname[24];
638         Script *script = G.main->script.first;
639         PyGILState_STATE gilstate;
640
641         if( !text )
642                 return 0;
643
644         /* check if this text is already running */
645         while( script ) {
646                 if( !strcmp( script->id.name + 2, text->id.name + 2 ) ) {
647                         /* if this text is already a running script, 
648                          * just move to it: */
649                         if (!G.background) {
650                                 SpaceScript *sc;
651                                 newspace( curarea, SPACE_SCRIPT );
652                                 sc = curarea->spacedata.first;
653                                 sc->script = script;
654                                 return 1;
655                         }
656                 }
657                 script = script->id.next;
658         }
659
660         /* Create a new script structure and initialize it: */
661         script = alloc_libblock( &G.main->script, ID_SCRIPT, text->id.name+2 );
662
663         if( !script ) {
664                 printf( "couldn't allocate memory for Script struct!" );
665                 return 0;
666         }
667
668         /* if in the script Blender.Load(blendfile) is not the last command,
669          * an error after it will call BPY_Err_Handle below, but the text struct
670          * will have been deallocated already, so we need to copy its name here.
671          */
672         BLI_strncpy( textname, text->id.name+2, 21 );
673
674         script->id.us = 1;
675         script->flags = SCRIPT_RUNNING;
676         script->py_draw = NULL;
677         script->py_event = NULL;
678         script->py_button = NULL;
679         script->py_browsercallback = NULL;
680         strncpy(script->scriptname, text->id.name+2, sizeof(script->scriptname));
681         gilstate = PyGILState_Ensure();
682
683         py_dict = CreateGlobalDictionary(  );
684
685         if( !setup_armature_weakrefs()){
686                 printf("Oops - weakref dict\n");
687                 PyGILState_Release(gilstate);
688                 return 0;
689         }
690
691         script->py_globaldict = py_dict;
692
693         info = ( BPy_constant * ) PyConstant_New(  );
694         if( info ) {
695                 PyConstant_Insert( info, "name",
696                                  PyString_FromString( script->id.name + 2 ) );
697                 Py_INCREF( Py_None );
698                 PyConstant_Insert( info, "arg", Py_None );
699                 EXPP_dict_set_item_str( py_dict, "__script__",
700                                       ( PyObject * ) info );
701         }
702
703         py_result = RunPython( text, py_dict ); /* Run the script */
704
705         if( !py_result ) {      /* Failed execution of the script */
706
707                 BPY_Err_Handle( textname );
708                 ReleaseGlobalDictionary( py_dict );
709                 script->py_globaldict = NULL;
710                 free_libblock( &G.main->script, script );
711                 PyGILState_Release(gilstate);
712                 return 0;
713         } else {
714                 Py_DECREF( py_result );
715                 script->flags &= ~SCRIPT_RUNNING;
716                 if( !script->flags ) {
717                         ReleaseGlobalDictionary( py_dict );
718                         script->py_globaldict = NULL;
719                         free_libblock( &G.main->script, script );
720                 }
721         }
722
723         PyGILState_Release(gilstate);
724
725         return 1;               /* normal return */
726 }
727
728 /****************************************************************************
729 * Description: Called from command line to run a Python script
730 * automatically. The script can be a file or a Blender Text in the current 
731 * .blend.
732 ****************************************************************************/
733 void BPY_run_python_script( const char *fn )
734 {
735         char filename[FILE_MAXDIR + FILE_MAXFILE];
736         Text *text = NULL;
737         int is_blender_text = 0;
738         
739         BLI_strncpy(filename, fn, FILE_MAXDIR + FILE_MAXFILE);
740         
741         if (!BLI_exists(filename))
742                 BLI_convertstringcwd(filename);
743                 
744         if (!BLI_exists(filename)) {    /* if there's no such filename ... */
745                 /* try an already existing Blender Text.
746                  * use 'fn' rather then filename for this since were looking for
747                  * internal text
748                  */
749                 text = G.main->text.first;
750
751                 while (text) {
752                         if (!strcmp(fn, text->id.name + 2)) break;
753                         text = text->id.next;
754                 }
755
756                 if (text == NULL) {
757                         printf("\nError: no such file or Blender text -- %s.\n", fn);
758                         return;
759                 }
760                 else is_blender_text = 1;       /* fn is already a Blender Text */
761         }
762
763         else {
764                 /* use filename here since we know it exists,
765                  * 'fn' may have been a relative path
766                  */
767                 text = add_text(filename);
768
769                 if (text == NULL) {
770                         printf("\nError in BPY_run_python_script:\n"
771                                 "couldn't create Blender text from \"%s\"\n", filename);
772                 /* Chris: On Windows if I continue I just get a segmentation
773                  * violation.  To get a baseline file I exit here. */
774                 exit(2);
775                 /* return; */
776                 }
777         }
778
779         if (BPY_txt_do_python_Text(text) != 1) {
780                 printf("\nError executing Python script from command-line:\n"
781                         "%s (at line %d).\n", fn, BPY_Err_getLinenumber());
782         }
783
784         if (!is_blender_text) {
785                 /* We can't simply free the text, since the script might have called
786                  * Blender.Load() to load a new .blend, freeing previous data.
787                  * So we check if the pointer is still valid. */
788                 if (BLI_findindex(&G.main->text, text) != -1) {
789                         free_libblock(&G.main->text, text);
790                 }
791         }
792 }
793
794 int BPY_run_script(Script *script)
795 {
796         PyObject *py_dict, *py_res, *pyarg;
797         Text *text = NULL;
798         BPy_constant *info;
799         
800         PyGILState_STATE gilstate = PyGILState_Ensure();
801         
802         if (!BLI_exists(script->scriptname)) {
803                 /* The file dosnt exist, maybe this blend file was made on some other persons computer? */
804                 char fname[FILE_MAX];
805                 char fpath[FILE_MAX];
806                 char ftmp[FILE_MAX];
807                 char *bpyhome = bpy_gethome(1);
808                 
809                 if (bpyhome) {
810                         BLI_strncpy(ftmp, script->scriptname, sizeof(ftmp));
811                         BLI_split_dirfile_basic(ftmp, NULL, fname); /* get the filename only - fname */
812                         BLI_strncpy(fpath, bpy_gethome(1), sizeof(fpath));
813                         BLI_add_slash(fpath);
814                         strcat(fpath, fname);
815                 
816                         if (BLI_exists(fpath)) {
817                                 strncpy(script->scriptname, fpath, sizeof(script->scriptname));
818                         } else {
819                                 bpyhome = NULL; /* a bit dodgy, this is so the line below runs */
820                         }
821                 }
822                 
823                 if (bpyhome == NULL && U.pythondir[0]) {
824                         BLI_make_file_string("/", fpath, U.pythondir, fname);
825                         if (BLI_exists(fpath)) {
826                                 strncpy(script->scriptname, fpath, sizeof(script->scriptname));
827                         }
828                 }
829                 
830                 /* cant find the file?, fallback to text block */
831                 if (!BLI_exists(script->scriptname)) {
832                         for (text=G.main->text.first; text; text=text->id.next) {
833                                 if (strcmp(script->scriptname, text->id.name+2)==0) {
834                                         break;
835                                 }
836                         }
837                 }
838         }
839         if (text) {
840                 Py_INCREF( Py_None );
841                 pyarg = Py_None;
842         } else {
843                 if (!BLI_exists(script->scriptname)) {
844                         printf( "Script does not exit %s\n", script->scriptname );
845                         free_libblock( &G.main->script, script );
846                         PyGILState_Release(gilstate);
847                         return 0;
848                 }
849                 
850                 if( script->scriptarg[0] == '\0' ) { /* no submenus */
851                         Py_INCREF( Py_None );
852                         pyarg = Py_None;
853                 } else {
854                         pyarg = PyString_FromString( script->scriptarg );
855                 }
856         }
857         
858         script->id.us = 1;
859         script->flags = SCRIPT_RUNNING;
860         script->py_draw = NULL;
861         script->py_event = NULL;
862         script->py_button = NULL;
863         script->py_browsercallback = NULL;
864         
865         py_dict = CreateGlobalDictionary(  );
866
867         script->py_globaldict = py_dict;
868
869         if( !setup_armature_weakrefs()){
870                 printf("Oops - weakref dict\n");
871                 free_libblock( &G.main->script, script );
872                 ReleaseGlobalDictionary( py_dict );
873                 PyGILState_Release(gilstate);
874                 return 0;
875         }
876         
877         info = ( BPy_constant * ) PyConstant_New(  );
878         if( info ) {
879                 PyConstant_Insert( info, "name",
880                                  PyString_FromString( script->id.name + 2 ) );
881                 PyConstant_Insert( info, "arg", pyarg );
882                 EXPP_dict_set_item_str( py_dict, "__script__",
883                                       ( PyObject * ) info );
884         }
885         
886         if (text) {
887                 py_res = RunPython( text, py_dict );
888         } else {
889                 char pystring[sizeof(script->scriptname) + 15];
890                 sprintf(pystring, "execfile(r'%s')", script->scriptname);
891                 py_res = PyRun_String( pystring, Py_file_input, py_dict, py_dict );
892         }
893
894         if( !py_res ) {         /* Failed execution of the script */
895                 /* Previously we used PyRun_File to run directly the code on a FILE 
896                 * object, but as written in the Python/C API Ref Manual, chapter 2,
897                 * 'FILE structs for different C libraries can be different and 
898                 * incompatible'.
899                 * So now we load the script file data to a buffer */
900                 BPY_Err_Handle( script->id.name + 2 );
901                 ReleaseGlobalDictionary( py_dict );
902                 script->py_globaldict = NULL;
903                 free_libblock( &G.main->script, script );
904                 error_pyscript(  );
905
906                 PyGILState_Release(gilstate);
907                 return 0;
908         } else {
909                 Py_DECREF( py_res );
910                 script->flags &= ~SCRIPT_RUNNING;
911
912                 if( !script->flags ) {
913                         ReleaseGlobalDictionary( py_dict );
914                         script->py_globaldict = NULL;
915                         free_libblock( &G.main->script, script );
916
917                         /* special case: called from the menu in the Scripts window
918                          * we have to change sc->script pointer, since it'll be freed here.*/
919                         if (!G.background) {
920                                 if( curarea->spacetype == SPACE_SCRIPT ) {
921                                         SpaceScript *sc = curarea->spacedata.first;
922                                         sc->script = G.main->script.first;      /* can be null, which is ok ... */
923                                         /* ... meaning no other script is running right now. */
924                                 }
925                         }
926
927                 }
928         }
929         
930         PyGILState_Release(gilstate);
931         return 1;
932 }
933         
934 /****************************************************************************
935 * Description: This function executes the script chosen from a menu.
936 * Notes:        It is called by the ui code in src/header_???.c when a user  
937 *               clicks on a menu entry that refers to a script.
938 *               Scripts are searched in the BPyMenuTable, using the given
939 *               menutype and event values to know which one was chosen. 
940 *****************************************************************************/
941 int BPY_menu_do_python( short menutype, int event )
942 {
943         BPyMenu *pym;
944         pym = BPyMenu_GetEntry( menutype, ( short ) event );
945         return BPY_menu_invoke( pym, menutype );
946 }
947         
948 /****************************************************************************
949 * Description: This function executes the script by its shortcut.
950 * Notes:        It is called by the ui code in src/???.c when a user presses an
951 *               unassigned key combination. Scripts are searched in the BPyMenuTable,
952 *               using the given menutype and event values to know which one to invoke.
953 *****************************************************************************/
954 int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short qual )
955 {
956         BPyMenu *pym;
957         pym = BPyMenu_GetEntry( menutype, 0 );
958
959         while ( pym ) {
960                 if ( pym->key && pym->key == key && pym->qual == qual ) {
961                         return BPY_menu_invoke( pym, menutype );
962                 }
963                 pym = pym->next;
964         }
965         
966         return 0;
967 }
968
969 /****************************************************************************
970 * Description: This function executes the script described by a menu item.
971 *****************************************************************************/
972 int BPY_menu_invoke( BPyMenu *pym, short menutype )
973 {
974         char *argstr = NULL;
975         BPySubMenu *pysm;
976         char scriptname[21];
977         Script *script = NULL;
978         int ret, len;
979         PyGILState_STATE gilstate;
980         char filestr[FILE_MAX];
981
982         if( !pym )
983                 return 0;
984
985         gilstate = PyGILState_Ensure();
986
987         if( pym->version > G.version )
988                 notice( "Version mismatch: script was written for Blender %d. "
989                         "It may fail with yours: %d.", pym->version,
990                         G.version );
991
992 /* if there are submenus, let the user choose one from a pupmenu that we
993  * create here.*/
994         pysm = pym->submenus;
995         if( pysm ) {
996                 char *pupstr;
997                 int arg;
998
999                 pupstr = BPyMenu_CreatePupmenuStr( pym, menutype );
1000
1001                 if( pupstr ) {
1002                         arg = pupmenu( pupstr );
1003                         MEM_freeN( pupstr );
1004
1005                         if( arg >= 0 ) {
1006                                 while( arg-- )
1007                                         pysm = pysm->next;
1008                                 argstr = pysm->arg;
1009                         } else {
1010                                 PyGILState_Release(gilstate);
1011                                 return 0;
1012                         }
1013                 }
1014         }
1015
1016         if( pym->dir ) { /* script is in U.pythondir */
1017                 char upythondir[FILE_MAX];
1018
1019                 /* dirs in Blender can be "//", which has a special meaning */
1020                 BLI_strncpy(upythondir, U.pythondir, FILE_MAX);
1021                 BLI_convertstringcode(upythondir, G.sce); /* if so, this expands it */
1022                 BLI_make_file_string( "/", filestr, upythondir, pym->filename );
1023         }
1024         else { /* script is in default scripts dir */
1025                 char *scriptsdir = bpy_gethome(1);
1026
1027                 if (!scriptsdir) {
1028                         printf("Error loading script: can't find default scripts dir!");
1029                         PyGILState_Release(gilstate);
1030                         return 0;
1031                 }
1032
1033                 BLI_make_file_string( "/", filestr, scriptsdir, pym->filename );
1034         }
1035
1036         BLI_strncpy(scriptname, pym->name, 21);
1037         len = strlen(scriptname) - 1;
1038         /* by convention, scripts that open the file browser or have submenus
1039          * display '...'.  Here we remove them from the datablock name */
1040         while ((len > 0) && scriptname[len] == '.') {
1041                 scriptname[len] = '\0';
1042                 len--;
1043         }
1044         
1045         /* Create a new script structure and initialize it: */
1046         script = alloc_libblock( &G.main->script, ID_SCRIPT, scriptname );
1047
1048         if( !script ) {
1049                 printf( "couldn't allocate memory for Script struct!" );
1050                 PyGILState_Release(gilstate);
1051                 return 0;
1052         }
1053
1054         /* let's find a proper area for an eventual script gui:
1055          * (still experimenting here, need definition on which win
1056          * each group will be put to code this properly) */
1057         switch ( menutype ) {
1058
1059         case PYMENU_IMPORT:     /* first 4 were handled in header_info.c */
1060         case PYMENU_EXPORT:
1061         case PYMENU_HELP:
1062         case PYMENU_RENDER:
1063         case PYMENU_WIZARDS:
1064         case PYMENU_SCRIPTTEMPLATE:
1065         case PYMENU_TEXTPLUGIN:
1066         case PYMENU_MESHFACEKEY:
1067                 break;
1068
1069         default:
1070                 if( curarea->spacetype != SPACE_SCRIPT ) {
1071                         ScrArea *sa = NULL;
1072
1073                         sa = find_biggest_area_of_type( SPACE_BUTS );
1074                         if( sa ) {
1075                                 if( ( 1.5 * sa->winx ) < sa->winy )
1076                                         sa = NULL;      /* too narrow? */
1077                         }
1078
1079                         if( !sa )
1080                                 sa = find_biggest_area_of_type( SPACE_SCRIPT );
1081                         if( !sa )
1082                                 sa = find_biggest_area_of_type( SPACE_TEXT );
1083                         if( !sa )
1084                                 sa = find_biggest_area_of_type( SPACE_IMAGE );  /* group UV */
1085                         if( !sa )
1086                                 sa = find_biggest_area_of_type( SPACE_VIEW3D );
1087
1088                         if( !sa )
1089                                 sa = find_biggest_area(  );
1090
1091                         areawinset( sa->win );
1092                 }
1093                 break;
1094         }
1095         
1096         strncpy(script->scriptname, filestr, sizeof(script->scriptname));
1097         if (argstr!=NULL && argstr[0] != '\0')
1098                 strncpy(script->scriptarg, argstr, sizeof(script->scriptarg));
1099         
1100         ret = BPY_run_script(script);
1101
1102         return 1;               /* normal return */
1103 }
1104
1105 /*****************************************************************************
1106 * Description:  
1107 * Notes:
1108 *****************************************************************************/
1109 void BPY_free_compiled_text( struct Text *text )
1110 {
1111         if( text->compiled ) {
1112                 Py_DECREF( ( PyObject * ) text->compiled );
1113                 text->compiled = NULL;
1114         }
1115 }
1116
1117 /*****************************************************************************
1118 * Description: This function frees a finished (flags == 0) script.
1119 *****************************************************************************/
1120 void BPY_free_finished_script( Script * script )
1121 {
1122         PyGILState_STATE gilstate;
1123
1124         if( !script )
1125                 return;
1126
1127         gilstate = PyGILState_Ensure();
1128
1129         if( PyErr_Occurred(  ) ) {      /* if script ended after filesel */
1130                 PyErr_Print(  );        /* eventual errors are handled now */
1131                 error_pyscript(  );
1132         }
1133
1134         PyGILState_Release(gilstate);
1135
1136         free_libblock( &G.main->script, script );
1137         return;
1138 }
1139
1140 static void unlink_script( Script * script )
1141 {       /* copied from unlink_text in drawtext.c */
1142         bScreen *scr;
1143         ScrArea *area;
1144         SpaceLink *sl;
1145
1146         for( scr = G.main->screen.first; scr; scr = scr->id.next ) {
1147                 for( area = scr->areabase.first; area; area = area->next ) {
1148                         for( sl = area->spacedata.first; sl; sl = sl->next ) {
1149                                 if( sl->spacetype == SPACE_SCRIPT ) {
1150                                         SpaceScript *sc = ( SpaceScript * ) sl;
1151
1152                                         if( sc->script == script ) {                                    
1153                                                 sc->script = NULL;
1154
1155                                                 if( sc == area->spacedata.first ) {
1156                                                         scrarea_queue_redraw( area );
1157                                                 }
1158                                                 
1159                                                 if (sc->but_refs) {
1160                                                         BPy_Set_DrawButtonsList(sc->but_refs);
1161                                                         BPy_Free_DrawButtonsList();
1162                                                         sc->but_refs = NULL;
1163                                                 }
1164                                         }
1165                                 }
1166                         }
1167                 }
1168         }
1169 }
1170
1171 /* This is called from free_libblock( &G.main->script, script ); */
1172 void BPY_clear_script( Script * script )
1173 {
1174         PyObject *dict;
1175         PyGILState_STATE gilstate;
1176
1177         if( !script )
1178                 return;
1179
1180         gilstate = PyGILState_Ensure();
1181
1182         if (!Py_IsInitialized()) {
1183                 printf("\nError: trying to free script data after finalizing Python!");
1184                 printf("\nScript name: %s\n", script->id.name+2);
1185                 PyGILState_Release(gilstate);
1186                 return;
1187         }
1188
1189         Py_XDECREF( ( PyObject * ) script->py_draw );
1190         Py_XDECREF( ( PyObject * ) script->py_event );
1191         Py_XDECREF( ( PyObject * ) script->py_button );
1192         Py_XDECREF( ( PyObject * ) script->py_browsercallback );
1193         script->py_draw = NULL;
1194         script->py_event = NULL;
1195         script->py_button = NULL;
1196         script->py_browsercallback = NULL;
1197         script->scriptname[0] = '\0';
1198         script->scriptarg[0] = '\0';
1199         
1200         dict = script->py_globaldict;
1201
1202         if( dict ) {
1203                 PyDict_Clear( dict );
1204                 Py_DECREF( dict );      /* Release dictionary. */
1205                 script->py_globaldict = NULL;
1206         }
1207
1208         PyGILState_Release(gilstate);
1209
1210         unlink_script( script );
1211 }
1212
1213 /* PyDrivers */
1214
1215 /* PyDrivers are Ipo Drivers governed by expressions written in Python.
1216  * Expressions here are one-liners that evaluate to a float value. */
1217
1218 /* For faster execution we keep a special dictionary for pydrivers, with
1219  * the needed modules and aliases. */
1220 static int bpy_pydriver_create_dict(void)
1221 {
1222         PyObject *d, *mod;
1223
1224         if (bpy_pydriver_Dict) return -1;
1225
1226         d = PyDict_New();
1227         if (!d) return -1;
1228
1229         bpy_pydriver_Dict = d;
1230
1231         /* import some modules: builtins, Blender, math, Blender.noise */
1232
1233         PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1234
1235         mod = PyImport_ImportModule("Blender");
1236         if (mod) {
1237                 PyDict_SetItemString(d, "Blender", mod);
1238                 PyDict_SetItemString(d, "b", mod);
1239                 Py_DECREF(mod);
1240         } else {
1241                 PyErr_Clear();
1242         }
1243
1244         mod = PyImport_ImportModule("math");
1245         if (mod) {
1246                 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
1247                 
1248                 /* Only keep for backwards compat! - just import all math into root, they are standard */
1249                 PyDict_SetItemString(d, "math", mod);
1250                 PyDict_SetItemString(d, "m", mod);
1251                 Py_DECREF(mod);
1252         } 
1253
1254         mod = PyImport_ImportModule("Blender.Noise");
1255         if (mod) {
1256                 PyDict_SetItemString(d, "noise", mod);
1257                 PyDict_SetItemString(d, "n", mod);
1258                 Py_DECREF(mod);
1259         } else {
1260                 PyErr_Clear();
1261         }
1262
1263         /* If there's a Blender text called pydrivers.py, import it.
1264          * Users can add their own functions to this module. */
1265         if (G.f&G_DOSCRIPTLINKS) {
1266                 mod = importText("pydrivers"); /* can also use PyImport_Import() */
1267                 if (mod) {
1268                         PyDict_SetItemString(d, "pydrivers", mod);
1269                         PyDict_SetItemString(d, "p", mod);
1270                         Py_DECREF(mod);
1271                 } else {
1272                         PyErr_Clear();
1273                 }
1274         }
1275         /* short aliases for some Get() functions: */
1276
1277         /* ob(obname) == Blender.Object.Get(obname) */
1278         mod = PyImport_ImportModule("Blender.Object");
1279         if (mod) {
1280                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1281                 Py_DECREF(mod);
1282                 if (fcn) {
1283                         PyDict_SetItemString(d, "ob", fcn);
1284                         Py_DECREF(fcn);
1285                 }
1286         } else {
1287                 PyErr_Clear();
1288         }
1289         
1290         /* TODO - change these */
1291         /* me(meshname) == Blender.Mesh.Get(meshname) */
1292         mod = PyImport_ImportModule("Blender.Mesh");
1293         if (mod) {
1294                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1295                 Py_DECREF(mod);
1296                 if (fcn) {
1297                         PyDict_SetItemString(d, "me", fcn);
1298                         Py_DECREF(fcn);
1299                 }
1300         } else {
1301                 PyErr_Clear();
1302         }
1303
1304         /* ma(matname) == Blender.Material.Get(matname) */
1305         mod = PyImport_ImportModule("Blender.Material");
1306         if (mod) {
1307                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1308                 Py_DECREF(mod);
1309                 if (fcn) {
1310                         PyDict_SetItemString(d, "ma", fcn);
1311                         Py_DECREF(fcn);
1312                 }
1313         } else {
1314                 PyErr_Clear();
1315         }
1316
1317         return 0;
1318 }
1319
1320 /* error return function for BPY_eval_pydriver */
1321 static float pydriver_error(IpoDriver *driver) {
1322
1323         if (bpy_pydriver_oblist)
1324                 bpy_pydriver_freeList();
1325
1326         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
1327                 PyDict_Clear(bpy_pydriver_Dict);
1328                 Py_DECREF(bpy_pydriver_Dict);
1329                 bpy_pydriver_Dict = NULL;
1330         }
1331
1332         driver->flag |= IPO_DRIVER_FLAG_INVALID; /* py expression failed */
1333         
1334         if (driver->ob)
1335                 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);
1336         else
1337                 fprintf(stderr, "\nError in Ipo Driver: No Object\nThis is the failed Python expression:\n'%s'\n\n", driver->name);
1338         
1339         PyErr_Print();
1340
1341         return 0.0f;
1342 }
1343
1344
1345 /********PyConstraints*********/
1346
1347 /* This function checks whether a text-buffer is a PyConstraint candidate.
1348  * It uses simple text parsing that could be easily confused!
1349  */
1350 int BPY_is_pyconstraint(Text *text)
1351 {
1352         TextLine *tline = text->lines.first;
1353
1354         if (tline && (tline->len > 10)) {
1355                 char *line = tline->line;
1356                 
1357                 /* Expected format: #BPYCONSTRAINT
1358                  * The actual checks are forgiving, so slight variations also work. */
1359                 if (line && line[0] == '#' && strstr(line, "BPYCONSTRAINT")) return 1;
1360         }
1361         return 0;
1362 }
1363
1364 /* This function frees links from pyconstraints to a given text-buffer.
1365  * Used when a text-buffer is unlinked!
1366  */
1367 void BPY_free_pyconstraint_links(Text *text)
1368 {
1369         Object *ob;
1370         bConstraint *con;
1371         short update;
1372         
1373         /*check all pyconstraints*/
1374         for (ob=G.main->object.first; ob; ob=ob->id.next) {
1375                 update = 0;
1376                 if(ob->type==OB_ARMATURE && ob->pose) {
1377                         bPoseChannel *pchan;
1378                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1379                                 for (con = pchan->constraints.first; con; con=con->next) {
1380                                         if (con->type==CONSTRAINT_TYPE_PYTHON) {
1381                                                 bPythonConstraint *data = con->data;
1382                                                 if (data->text==text) data->text = NULL;
1383                                                 update = 1;
1384                                                 
1385                                         }
1386                                 }
1387                         }
1388                 }
1389                 for (con = ob->constraints.first; con; con=con->next) {
1390                         if (con->type==CONSTRAINT_TYPE_PYTHON) {
1391                                 bPythonConstraint *data = con->data;
1392                                 if (data->text==text) data->text = NULL;
1393                                 update = 1;
1394                         }
1395                 }
1396                 
1397                 if (update) {
1398                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1399                 }
1400         }
1401 }
1402
1403 /* This function is called to update PyConstraint data so that it is compatible with the script. 
1404  * Some of the allocating/freeing of memory for constraint targets occurs here, espcially
1405  * if the number of targets changes.
1406  */
1407 void BPY_pyconstraint_update(Object *owner, bConstraint *con)
1408 {
1409         bPythonConstraint *data= con->data;
1410         
1411         if (data->text) {       
1412                 /* script does exist. it is assumed that this is a valid pyconstraint script */
1413                 PyObject *globals;
1414                 PyObject *retval, *gval;
1415                 PyGILState_STATE gilstate;
1416                 int num, i;
1417                 
1418                 /* clear the relevant flags first */
1419                 data->flag = 0;
1420
1421                 gilstate = PyGILState_Ensure();
1422
1423                 /* populate globals dictionary */
1424                 globals = CreateGlobalDictionary();
1425                 retval = RunPython(data->text, globals);
1426                 
1427                 if (retval == NULL) {
1428                         BPY_Err_Handle(data->text->id.name);
1429                         ReleaseGlobalDictionary(globals);
1430                         data->flag |= PYCON_SCRIPTERROR;
1431                         PyGILState_Release(gilstate);
1432                         return;
1433                 }
1434                 
1435                 Py_XDECREF(retval);
1436                 retval = NULL;
1437                 
1438                 /* try to find NUM_TARGETS */
1439                 gval = PyDict_GetItemString(globals, "NUM_TARGETS");
1440                 if ( (gval) && (num= PyInt_AsLong(gval)) ) {
1441                         /* NUM_TARGETS is defined... and non-zero */
1442                         bConstraintTarget *ct;
1443                         
1444                         /* check if it is valid (just make sure it is not negative)
1445                          *      TODO: PyInt_AsLong may return -1 as sign of invalid input... 
1446                          */
1447                         num = abs(num);
1448                         data->flag |= PYCON_USETARGETS;
1449                         
1450                         /* check if the number of targets has changed */
1451                         if (num < data->tarnum) {
1452                                 /* free a few targets */
1453                                 num= data->tarnum - num;
1454                                 for (i = 0; i < num; i++, data->tarnum--) {
1455                                         ct= data->targets.last;
1456                                         BLI_freelinkN(&data->targets, ct);
1457                                 }
1458                         }
1459                         else if (num > data->tarnum) {
1460                                 /* add a few targets */
1461                                 num = num - data->tarnum;
1462                                 for (i = 0; i < num; i++, data->tarnum++) {
1463                                         ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
1464                                         BLI_addtail(&data->targets, ct);
1465                                 }
1466                         }
1467                         
1468                         /* validate targets */
1469                         con->flag &= ~CONSTRAINT_DISABLE;
1470                         for (ct= data->targets.first; ct; ct= ct->next) {
1471                                 if (!exist_object(ct->tar)) {
1472                                         ct->tar = NULL;
1473                                         con->flag |= CONSTRAINT_DISABLE;
1474                                         break;
1475                                 }
1476                                 
1477                                 if ((ct->tar == owner) && (ct->subtarget[0] != 0)) {
1478                                         if (get_named_bone(get_armature(owner), ct->subtarget) == NULL) {
1479                                                 con->flag |= CONSTRAINT_DISABLE;
1480                                                 break;
1481                                         }
1482                                 }
1483                         }
1484                         
1485                         /* clear globals */
1486                         ReleaseGlobalDictionary(globals);
1487
1488                         PyGILState_Release(gilstate);
1489
1490                         return;
1491                 }
1492                 else {
1493                         /* NUM_TARGETS is not defined or equals 0 */
1494                         ReleaseGlobalDictionary(globals);
1495                         
1496                         /* free all targets */
1497                         BLI_freelistN(&data->targets);
1498                         data->tarnum = 0;
1499                         data->flag &= ~PYCON_USETARGETS;
1500                         
1501                         PyGILState_Release(gilstate);
1502
1503                         return;
1504                 }
1505         }
1506         else {
1507                 /* no script, so clear any settings/data now */
1508                 data->tarnum = 0;
1509                 data->flag = 0;
1510                 con->flag &= ~CONSTRAINT_DISABLE;
1511                 
1512                 BLI_freelistN(&data->targets);
1513                 
1514                 /* supposedly this should still leave the base struct... */
1515                 IDP_FreeProperty(data->prop);
1516         }
1517 }
1518
1519 /* PyConstraints Evaluation Function (only called from evaluate_constraint)
1520  * This function is responsible for modifying the ownermat that it is passed. 
1521  */
1522 void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase *targets)
1523 {
1524         PyObject *srcmat, *tarmat, *tarmats, *idprop;
1525         PyObject *globals;
1526         PyObject *gval;
1527         PyObject *pyargs, *retval;
1528         bConstraintTarget *ct;
1529         MatrixObject *retmat;
1530         int row, col, index;
1531         PyGILState_STATE gilstate;
1532
1533         if (!con->text) return;
1534         if (con->flag & PYCON_SCRIPTERROR) return;
1535
1536         gilstate = PyGILState_Ensure();
1537
1538         globals = CreateGlobalDictionary();
1539         
1540         /* wrap blender-data as PyObjects for evaluation 
1541          *      - we expose the owner's matrix as pymatrix
1542          *      - id-properties are wrapped using the id-properties pyapi
1543          *      - targets are presented as a list of matrices
1544          */
1545         srcmat = newMatrixObject((float *)cob->matrix, 4, 4, Py_NEW);
1546         idprop = BPy_Wrap_IDProperty(NULL, con->prop, NULL);
1547         
1548         tarmats= PyList_New(con->tarnum); 
1549         for (ct=targets->first, index=0; ct; ct=ct->next, index++) {
1550                 tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1551                 PyList_SET_ITEM(tarmats, index, tarmat);
1552         }
1553         
1554         if (!setup_armature_weakrefs()) {
1555                 fprintf(stderr, "Oops - weakref dict setup\n");
1556                 PyGILState_Release(gilstate);
1557
1558                 return;
1559         }
1560         
1561         retval = RunPython(con->text, globals);
1562         
1563         if (retval == NULL) {
1564                 BPY_Err_Handle(con->text->id.name);
1565                 con->flag |= PYCON_SCRIPTERROR;
1566                 
1567                 /* free temp objects */
1568                 Py_XDECREF(idprop);
1569                 Py_XDECREF(srcmat);
1570                 Py_XDECREF(tarmats);
1571                 
1572                 ReleaseGlobalDictionary(globals);
1573
1574                 PyGILState_Release(gilstate);
1575
1576                 return;
1577         }
1578
1579         if (retval) {Py_XDECREF( retval );}
1580         retval = NULL;
1581         
1582         gval = PyDict_GetItemString(globals, "doConstraint");
1583         if (!gval) {
1584                 printf("ERROR: no doConstraint function in constraint!\n");
1585                 
1586                 /* free temp objects */
1587                 Py_XDECREF(idprop);
1588                 Py_XDECREF(srcmat);
1589                 Py_XDECREF(tarmats);
1590                 
1591                 ReleaseGlobalDictionary(globals);
1592
1593                 PyGILState_Release(gilstate);
1594
1595                 return;
1596         }
1597         
1598         /* Now for the fun part! Try and find the functions we need. */
1599         if (PyFunction_Check(gval)) {
1600                 pyargs = Py_BuildValue("OOO", srcmat, tarmats, idprop);
1601                 retval = PyObject_CallObject(gval, pyargs);
1602                 Py_XDECREF(pyargs);
1603         } 
1604         else {
1605                 printf("ERROR: doConstraint is supposed to be a function!\n");
1606                 con->flag |= PYCON_SCRIPTERROR;
1607                 
1608                 Py_XDECREF(idprop);
1609                 Py_XDECREF(srcmat);
1610                 Py_XDECREF(tarmats);
1611                 
1612                 ReleaseGlobalDictionary(globals);
1613
1614                 PyGILState_Release(gilstate);
1615
1616                 return;
1617         }
1618         
1619         if (!retval) {
1620                 BPY_Err_Handle(con->text->id.name);
1621                 con->flag |= PYCON_SCRIPTERROR;
1622                 
1623                 /* free temp objects */
1624                 Py_XDECREF(idprop);
1625                 Py_XDECREF(srcmat);
1626                 Py_XDECREF(tarmats);
1627                 
1628                 ReleaseGlobalDictionary(globals);
1629
1630                 PyGILState_Release(gilstate);
1631
1632                 return;
1633         }
1634         
1635         
1636         if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1637                 printf("Error in PyConstraint - doConstraint: Function not returning a matrix!\n");
1638                 con->flag |= PYCON_SCRIPTERROR;
1639                 
1640                 Py_XDECREF(idprop);
1641                 Py_XDECREF(srcmat);
1642                 Py_XDECREF(tarmats);
1643                 Py_XDECREF(retval);
1644                 
1645                 ReleaseGlobalDictionary(globals);
1646
1647                 PyGILState_Release(gilstate);
1648
1649                 return;
1650         }
1651         
1652         retmat = (MatrixObject *)retval;
1653         if (retmat->rowSize != 4 || retmat->colSize != 4) {
1654                 printf("Error in PyConstraint - doConstraint: Matrix returned is the wrong size!\n");
1655                 con->flag |= PYCON_SCRIPTERROR;
1656                 
1657                 Py_XDECREF(idprop);
1658                 Py_XDECREF(srcmat);
1659                 Py_XDECREF(tarmats);
1660                 Py_XDECREF(retval);
1661                 
1662                 ReleaseGlobalDictionary(globals);
1663
1664                 PyGILState_Release(gilstate);
1665
1666                 return;
1667         }       
1668
1669         /* this is the reverse of code taken from newMatrix() */
1670         for(row = 0; row < 4; row++) {
1671                 for(col = 0; col < 4; col++) {
1672                         cob->matrix[row][col] = retmat->contigPtr[row*4+col];
1673                 }
1674         }
1675         
1676         /* free temp objects */
1677         Py_XDECREF(idprop);
1678         Py_XDECREF(srcmat);
1679         Py_XDECREF(tarmats);
1680         Py_XDECREF(retval);
1681         
1682         /* clear globals */
1683         ReleaseGlobalDictionary(globals);
1684
1685         PyGILState_Release(gilstate);
1686 }
1687
1688 /* This evaluates the target matrix for each target the PyConstraint uses.
1689  * NOTE: it only does one target at a time!
1690  */
1691 void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
1692 {
1693         PyObject *tar, *subtar;
1694         PyObject *tarmat, *idprop;
1695         PyObject *globals;
1696         PyObject *gval;
1697         PyObject *pyargs, *retval;
1698         MatrixObject *retmat;
1699         int row, col;
1700         PyGILState_STATE gilstate;
1701
1702         if (!con->text) return;
1703         if (con->flag & PYCON_SCRIPTERROR) return;
1704         if (!ct) return;
1705         
1706         gilstate = PyGILState_Ensure();
1707
1708         globals = CreateGlobalDictionary();
1709         
1710         tar = Object_CreatePyObject(ct->tar);
1711         if ((ct->tar) && (ct->tar->type==OB_ARMATURE)) {
1712                 bPoseChannel *pchan;
1713                 pchan = get_pose_channel(ct->tar->pose, ct->subtarget);
1714                 subtar = PyPoseBone_FromPosechannel(pchan);
1715         }
1716         else
1717                 subtar = PyString_FromString(ct->subtarget);
1718         
1719         tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1720         idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1721         
1722         if (!setup_armature_weakrefs()) {
1723                 fprintf(stderr, "Oops - weakref dict setup\n");
1724                 PyGILState_Release(gilstate);
1725                 return;
1726         }
1727         
1728         retval = RunPython(con->text, globals);
1729
1730         if (retval == NULL) {
1731                 BPY_Err_Handle(con->text->id.name);
1732                 con->flag |= PYCON_SCRIPTERROR;
1733                 
1734                 /* free temp objects */
1735                 Py_XDECREF(tar);
1736                 Py_XDECREF(subtar);
1737                 Py_XDECREF(idprop);
1738                 Py_XDECREF(tarmat);
1739                 
1740                 ReleaseGlobalDictionary(globals);
1741
1742                 PyGILState_Release(gilstate);
1743
1744                 return;
1745         }
1746
1747         Py_XDECREF(retval);
1748         retval = NULL;
1749         
1750         /* try to find doTarget function to set the target matrix */
1751         gval = PyDict_GetItemString(globals, "doTarget");
1752         if (!gval) {
1753                 /* free temp objects */
1754                 Py_XDECREF(tar);
1755                 Py_XDECREF(subtar);
1756                 Py_XDECREF(idprop);
1757                 Py_XDECREF(tarmat);
1758                 
1759                 ReleaseGlobalDictionary(globals);
1760
1761                 PyGILState_Release(gilstate);
1762
1763                 return;
1764         }
1765         
1766         /* Now for the fun part! Try and find the functions we need.*/
1767         if (PyFunction_Check(gval)) {
1768                 pyargs = Py_BuildValue("OOOO", tar, subtar, tarmat, idprop);
1769                 retval = PyObject_CallObject(gval, pyargs);
1770                 Py_XDECREF(pyargs);
1771         } 
1772         else {
1773                 printf("ERROR: doTarget is supposed to be a function!\n");
1774                 con->flag |= PYCON_SCRIPTERROR;
1775                 
1776                 Py_XDECREF(tar);
1777                 Py_XDECREF(subtar);
1778                 Py_XDECREF(idprop);
1779                 Py_XDECREF(tarmat);
1780                 
1781                 ReleaseGlobalDictionary(globals);
1782
1783                 PyGILState_Release(gilstate);
1784
1785                 return;
1786         }
1787         
1788         if (!retval) {
1789                 BPY_Err_Handle(con->text->id.name);
1790                 con->flag |= PYCON_SCRIPTERROR;
1791                 
1792                 
1793                 /* free temp objects */
1794                 Py_XDECREF(tar);
1795                 Py_XDECREF(subtar);
1796                 Py_XDECREF(idprop);
1797                 Py_XDECREF(tarmat);
1798                 
1799                 ReleaseGlobalDictionary(globals);
1800
1801                 PyGILState_Release(gilstate);
1802
1803                 return;
1804         }
1805         
1806         if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1807                 con->flag |= PYCON_SCRIPTERROR;
1808                 
1809                 Py_XDECREF(tar);
1810                 Py_XDECREF(subtar);
1811                 Py_XDECREF(idprop);
1812                 Py_XDECREF(tarmat);
1813                 Py_XDECREF(retval);
1814                 
1815                 ReleaseGlobalDictionary(globals);
1816
1817                 PyGILState_Release(gilstate);
1818
1819                 return;
1820         }
1821         
1822         retmat = (MatrixObject *)retval;
1823         if (retmat->rowSize != 4 || retmat->colSize != 4) {
1824                 printf("Error in PyConstraint - doTarget: Matrix returned is the wrong size!\n");
1825                 con->flag |= PYCON_SCRIPTERROR;
1826                 
1827                 Py_XDECREF(tar);
1828                 Py_XDECREF(subtar);
1829                 Py_XDECREF(idprop);
1830                 Py_XDECREF(tarmat);
1831                 Py_XDECREF(retval);
1832                 
1833                 ReleaseGlobalDictionary(globals);
1834
1835                 PyGILState_Release(gilstate);
1836
1837                 return;
1838         }       
1839
1840         /* this is the reverse of code taken from newMatrix() */
1841         for(row = 0; row < 4; row++) {
1842                 for(col = 0; col < 4; col++) {
1843                         ct->matrix[row][col] = retmat->contigPtr[row*4+col];
1844                 }
1845         }
1846         
1847         /* free temp objects */
1848         Py_XDECREF(tar);
1849         Py_XDECREF(subtar);
1850         Py_XDECREF(idprop);
1851         Py_XDECREF(tarmat);
1852         Py_XDECREF(retval);
1853         
1854         /* clear globals */
1855         ReleaseGlobalDictionary(globals);
1856
1857         PyGILState_Release(gilstate);
1858 }
1859
1860 /* This draws+handles the user-defined interface for editing pyconstraints idprops */
1861 void BPY_pyconstraint_settings(void *arg1, void *arg2)
1862 {
1863         bPythonConstraint *con= (bPythonConstraint *)arg1;
1864         PyObject *idprop;
1865         PyObject *globals;
1866         PyObject *gval;
1867         PyObject *retval;
1868         PyGILState_STATE gilstate;
1869         
1870         if (!con->text) return;
1871         if (con->flag & PYCON_SCRIPTERROR) return;
1872         
1873         gilstate = PyGILState_Ensure();
1874         
1875         globals = CreateGlobalDictionary();
1876         
1877         idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1878         
1879         retval = RunPython(con->text, globals);
1880
1881         if (retval == NULL) {
1882                 BPY_Err_Handle(con->text->id.name);
1883                 ReleaseGlobalDictionary(globals);
1884                 con->flag |= PYCON_SCRIPTERROR;
1885                 
1886                 /* free temp objects */
1887                 Py_XDECREF(idprop);
1888                 
1889                 PyGILState_Release(gilstate);
1890                 
1891                 return;
1892         }
1893
1894         if (retval) {Py_XDECREF( retval );}
1895         retval = NULL;
1896         
1897         gval = PyDict_GetItemString(globals, "getSettings");
1898         if (!gval) {
1899                 printf("ERROR: no getSettings function in constraint!\n");
1900                 
1901                 /* free temp objects */
1902                 ReleaseGlobalDictionary( globals );
1903                 Py_XDECREF(idprop);
1904
1905                 PyGILState_Release(gilstate);
1906
1907                 return;
1908         }
1909         
1910         /* Now for the fun part! Try and find the functions we need. */
1911         if (PyFunction_Check(gval)) {
1912                 retval = PyObject_CallFunction(gval, "O", idprop);
1913         } 
1914         else {
1915                 printf("ERROR: getSettings is supposed to be a function!\n");
1916                 ReleaseGlobalDictionary( globals );
1917                 
1918                 Py_XDECREF(idprop);
1919                 
1920                 PyGILState_Release(gilstate);
1921                 
1922                 return;
1923         }
1924         
1925         if (!retval) {
1926                 BPY_Err_Handle(con->text->id.name);
1927                 con->flag |= PYCON_SCRIPTERROR;
1928                 
1929                 /* free temp objects */
1930                 ReleaseGlobalDictionary(globals);
1931                 Py_XDECREF(idprop);
1932                 
1933                 PyGILState_Release(gilstate);
1934                 
1935                 return;
1936         }
1937         else {
1938                 /* clear globals */
1939                 ReleaseGlobalDictionary(globals);
1940                 
1941                 /* free temp objects */
1942                 Py_XDECREF(idprop);
1943                 Py_DECREF(retval);
1944                 
1945                 PyGILState_Release(gilstate);
1946                 
1947                 return;
1948         }
1949 }
1950
1951 /* Update function, it gets rid of pydrivers global dictionary, forcing
1952  * BPY_pydriver_eval to recreate it. This function is used to force
1953  * reloading the Blender text module "pydrivers.py", if available, so
1954  * updates in it reach pydriver evaluation. */
1955 void BPY_pydriver_update(void)
1956 {
1957         PyGILState_STATE gilstate = PyGILState_Ensure();
1958
1959         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
1960                 PyDict_Clear(bpy_pydriver_Dict);
1961                 Py_DECREF(bpy_pydriver_Dict);
1962                 bpy_pydriver_Dict = NULL;
1963         }
1964
1965         PyGILState_Release(gilstate);
1966
1967         return;
1968 }
1969
1970 /* for depsgraph.c, runs py expr once to collect all refs. made
1971  * to objects (self refs. to the object that owns the py driver
1972  * are not allowed). */
1973 struct Object **BPY_pydriver_get_objects(IpoDriver *driver)
1974 {
1975         /*if (!driver || !driver->ob || driver->name[0] == '\0')
1976                 return NULL;*/
1977
1978         /*PyErr_Clear();*/
1979
1980         /* clear the flag that marks invalid python expressions */
1981         driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
1982
1983         /* tell we're running a pydriver, so Get() functions know they need
1984          * to add the requested obj to our list */
1985         bpy_pydriver_running(1);
1986
1987         /* append driver owner object as the 1st ob in the list;
1988          * we put it there to make sure it is not itself referenced in
1989          * its pydriver expression */
1990         bpy_pydriver_appendToList(driver->ob);
1991
1992         /* this will append any other ob referenced in expr (driver->name)
1993          * or set the driver's error flag if driver's py expression fails */
1994         BPY_pydriver_eval(driver);
1995
1996         bpy_pydriver_running(0); /* ok, we're done */
1997
1998         return bpy_pydriver_obArrayFromList(); /* NULL if eval failed */
1999 }
2000
2001 /* This evals py driver expressions, 'expr' is a Python expression that
2002  * should evaluate to a float number, which is returned. */
2003 float BPY_pydriver_eval(IpoDriver *driver)
2004 {
2005         char *expr = NULL;
2006         PyObject *retval, *bpy_ob = NULL;
2007         float result = 0.0f; /* default return */
2008         int setitem_retval;
2009         PyGILState_STATE gilstate;
2010
2011         if (!driver ||  (G.f&G_DOSCRIPTLINKS)==0) return result;
2012
2013         expr = driver->name; /* the py expression to be evaluated */
2014         if (!expr || expr[0]=='\0') return result;
2015
2016         gilstate = PyGILState_Ensure();
2017
2018         if (!bpy_pydriver_Dict) {
2019                 if (bpy_pydriver_create_dict() != 0) {
2020                         fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
2021                         PyGILState_Release(gilstate);
2022                         return result;
2023                 }
2024         }
2025
2026         if (driver->ob)
2027                 bpy_ob = Object_CreatePyObject(driver->ob);
2028
2029         if (!bpy_ob) {
2030                 Py_INCREF(Py_None);
2031                 bpy_ob = Py_None;
2032         }
2033
2034         setitem_retval = EXPP_dict_set_item_str(bpy_pydriver_Dict, "self", bpy_ob);
2035
2036         if( !setup_armature_weakrefs()){
2037                 fprintf( stderr, "Oops - weakref dict setup\n");
2038                 PyGILState_Release(gilstate);
2039                 return result;
2040         }
2041
2042         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
2043                 bpy_pydriver_Dict);
2044
2045         if (retval == NULL) {
2046                 result = pydriver_error(driver);
2047                 PyGILState_Release(gilstate);
2048                 return result;
2049         }
2050
2051         result = ( float )PyFloat_AsDouble( retval );
2052         Py_DECREF(retval);
2053         
2054         if (result == -1 && PyErr_Occurred()) {
2055                 result = pydriver_error(driver);
2056                 PyGILState_Release(gilstate);
2057                 return result;
2058         }
2059
2060         /* remove 'self', since this dict is also used by py buttons */
2061         if (setitem_retval == 0) PyDict_DelItemString(bpy_pydriver_Dict, "self");
2062
2063         /* all fine, make sure the "invalid expression" flag is cleared */
2064         driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
2065
2066         PyGILState_Release(gilstate);
2067
2068         return result;
2069 }
2070
2071 /* Button Python Evaluation */
2072
2073 /* Python evaluation for gui buttons:
2074  *      users can write any valid Python expression (that evals to an int or float)
2075  *      inside Blender's gui number buttons and have them evaluated to their
2076  *      actual int or float value.
2077  *
2078  *      The global dict used for pydrivers is also used here, so all imported
2079  *      modules for pydrivers (including the pydrivers.py Blender text) are
2080  *      available for button py eval, too. */
2081
2082 static int bpy_button_eval_error(char *expr) {
2083
2084         if (bpy_pydriver_oblist)
2085                 bpy_pydriver_freeList();
2086
2087         if (bpy_pydriver_Dict) { /* free the persistent global dict */
2088                 /* it's the same dict used by pydrivers */
2089                 PyDict_Clear(bpy_pydriver_Dict);
2090                 Py_DECREF(bpy_pydriver_Dict);
2091                 bpy_pydriver_Dict = NULL;
2092         }
2093
2094         fprintf(stderr, "\nError in button evaluation:\nThis is the failed Python expression:\n'%s'\n\n", expr);
2095
2096         PyErr_Print();
2097
2098         return -1;
2099 }
2100
2101 int BPY_button_eval(char *expr, double *value)
2102 {
2103         PyObject *retval, *floatval;
2104         PyGILState_STATE gilstate;
2105         int ret;
2106
2107         if (!value || !expr || expr[0]=='\0') return -1;
2108
2109         *value = 0.0; /* default value */
2110
2111         gilstate = PyGILState_Ensure();
2112
2113         if (!bpy_pydriver_Dict) {
2114                 if (bpy_pydriver_create_dict() != 0) {
2115                         fprintf(stderr,
2116                                 "Button Python Eval error: couldn't create Python dictionary \n");
2117                         PyGILState_Release(gilstate);
2118                         return -1;
2119                 }
2120         }
2121
2122
2123         if( !setup_armature_weakrefs()){
2124                 fprintf(stderr, "Oops - weakref dict\n");
2125                 PyGILState_Release(gilstate);
2126                 return -1;
2127         }
2128
2129         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
2130                 bpy_pydriver_Dict);
2131
2132         if (retval == NULL) {
2133                 ret = bpy_button_eval_error(expr);
2134                 PyGILState_Release(gilstate);
2135                 return ret;
2136         }
2137         else {
2138                 floatval = PyNumber_Float(retval);
2139                 Py_DECREF(retval);
2140         }
2141
2142         if (floatval == NULL) {
2143                 ret = bpy_button_eval_error(expr);
2144                 PyGILState_Release(gilstate);
2145                 return ret;
2146         } else {
2147                 *value = (float)PyFloat_AsDouble(floatval);
2148                 Py_DECREF(floatval);
2149         }
2150
2151         PyGILState_Release(gilstate);
2152
2153         return 0; /* successful exit */
2154 }
2155
2156
2157 /*****************************************************************************/
2158 /* ScriptLinks                                                        */
2159 /*****************************************************************************/
2160
2161 /*****************************************************************************/
2162 /* Description:                                                          */
2163 /* Notes:                               Not implemented yet      */
2164 /*****************************************************************************/
2165 void BPY_clear_bad_scriptlinks( struct Text *byebye )
2166 {
2167 /*
2168         BPY_clear_bad_scriptlist(getObjectList(), byebye);
2169         BPY_clear_bad_scriptlist(getLampList(), byebye);
2170         BPY_clear_bad_scriptlist(getCameraList(), byebye);
2171         BPY_clear_bad_scriptlist(getMaterialList(), byebye);
2172         BPY_clear_bad_scriptlist(getWorldList(),        byebye);
2173         BPY_clear_bad_scriptlink(&scene_getCurrent()->id, byebye);
2174
2175         allqueue(REDRAWBUTSSCRIPT, 0);
2176 */
2177         return;
2178 }
2179
2180 /*****************************************************************************
2181 * Description: Loop through all scripts of a list of object types, and 
2182 *       execute these scripts.  
2183 *       For the scene, only the current active scene the scripts are 
2184 *       executed (if any).
2185 *****************************************************************************/
2186 void BPY_do_all_scripts( short event, short anim )
2187 {
2188         /* during stills rendering we disable FRAMECHANGED events */
2189         static char disable_frame_changed = 0;
2190
2191         if ((event == SCRIPT_FRAMECHANGED) && disable_frame_changed)
2192                 return;
2193
2194         DoAllScriptsFromList( &( G.main->object ), event );
2195         DoAllScriptsFromList( &( G.main->lamp ), event );
2196         DoAllScriptsFromList( &( G.main->camera ), event );
2197         DoAllScriptsFromList( &( G.main->mat ), event );
2198         DoAllScriptsFromList( &( G.main->world ), event );
2199
2200         BPY_do_pyscript( &( G.scene->id ), event );
2201
2202         /* Don't allow the Python Interpreter to release the GIL on
2203          * its own, to guarantee PyNodes work properly. For Blender this
2204          * is currently the best default behavior.
2205          * The following code in C is equivalent in Python to:
2206          * "import sys; sys.setcheckinterval(sys.maxint)" */
2207         if (event == SCRIPT_RENDER) {
2208                 _Py_CheckInterval = PyInt_GetMax();
2209                 if (!anim)
2210                         disable_frame_changed = 1;
2211         }
2212         else if (event == SCRIPT_POSTRENDER) {
2213                 _Py_CheckInterval = 100; /* Python default */
2214                 disable_frame_changed = 0;
2215         }
2216
2217         return;
2218 }
2219
2220 /*****************************************************************************
2221 * Description: Execute a Python script when an event occurs. The following  
2222 *               events are possible: frame changed, load script and redraw.  
2223 *               Only events happening to one of the following object types   
2224 *               are handled: Object, Lamp, Camera, Material, World and      
2225 *               Scene.                  
2226 *****************************************************************************/
2227
2228 static ScriptLink *ID_getScriptlink( ID * id )
2229 {
2230         switch ( MAKE_ID2( id->name[0], id->name[1] ) ) {
2231         case ID_OB:
2232                 return &( ( Object * ) id )->scriptlink;
2233         case ID_LA:
2234                 return &( ( Lamp * ) id )->scriptlink;
2235         case ID_CA:
2236                 return &( ( Camera * ) id )->scriptlink;
2237         case ID_MA:
2238                 return &( ( Material * ) id )->scriptlink;
2239         case ID_WO:
2240                 return &( ( World * ) id )->scriptlink;
2241         case ID_SCE:
2242                 return &( ( Scene * ) id )->scriptlink;
2243         default:
2244                 return NULL;
2245         }
2246 }
2247
2248 int BPY_has_onload_script( void )
2249 {
2250         ScriptLink *slink = &G.scene->scriptlink;
2251         int i;
2252
2253         if( !slink || !slink->totscript )
2254                 return 0;
2255
2256         for( i = 0; i < slink->totscript; i++ ) {
2257                 if( ( slink->flag[i] == SCRIPT_ONLOAD )
2258                     && ( slink->scripts[i] != NULL ) )
2259                         return 1;
2260         }
2261
2262         return 0;
2263 }
2264
2265 void BPY_do_pyscript( ID * id, short event )
2266 {
2267         ScriptLink *scriptlink;
2268
2269         if( !id ) return;
2270
2271         scriptlink = ID_getScriptlink( id );
2272
2273         if( scriptlink && scriptlink->totscript ) {
2274                 PyObject *value;
2275                 PyObject *dict;
2276                 PyObject *ret;
2277                 int index, during_slink = during_scriptlink(  );
2278                 PyGILState_STATE gilstate;
2279
2280                 /* invalid scriptlinks (new .blend was just loaded), return */
2281                 if( during_slink < 0 )
2282                         return;
2283
2284                 gilstate = PyGILState_Ensure();
2285
2286                 if( !setup_armature_weakrefs()){
2287                         printf("Oops - weakref dict, this is a bug\n");
2288                         PyGILState_Release(gilstate);
2289                         return;
2290                 }
2291                 
2292                 value = GetPyObjectFromID( id );
2293                 if( !value){
2294                         printf("Oops - could not get a valid python object for Blender.link, this is a bug\n");
2295                         PyGILState_Release(gilstate);
2296                         return;
2297                 }
2298                 
2299                 /* tell we're running a scriptlink.  The sum also tells if this
2300                  * script is running nested inside another.  Blender.Load needs
2301                  * this info to avoid trouble with invalid slink pointers. */
2302                 during_slink++;
2303                 disable_where_scriptlink( (short)during_slink );
2304
2305                 /* set globals in Blender module to identify scriptlink */
2306                 PyDict_SetItemString(   g_blenderdict, "bylink", Py_True);
2307                 EXPP_dict_set_item_str( g_blenderdict, "link", value );
2308                 EXPP_dict_set_item_str( g_blenderdict, "event",
2309                                       PyString_FromString( event_to_name
2310                                                            ( event ) ) );
2311                 if (event == SCRIPT_POSTRENDER) event = SCRIPT_RENDER;
2312
2313                 for( index = 0; index < scriptlink->totscript; index++ ) {
2314                         if( ( scriptlink->flag[index] == event ) &&
2315                             ( scriptlink->scripts[index] != NULL ) ) {
2316                                 dict = CreateGlobalDictionary(  );
2317                                 ret = RunPython( ( Text * ) scriptlink->
2318                                                  scripts[index], dict );
2319                                 ReleaseGlobalDictionary( dict );
2320
2321                                 if( !ret ) {
2322                                         /* Failed execution of the script */
2323                                         BPY_Err_Handle( scriptlink->
2324                                                         scripts[index]->name +
2325                                                         2 );
2326                                         //BPY_end_python ();
2327                                         //BPY_start_python ();
2328                                 } else {
2329                                         Py_DECREF( ret );
2330                                 }
2331                                 /* If a scriptlink has just loaded a new .blend file, the
2332                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
2333                                  * so we stop here. */
2334                                 if( during_scriptlink(  ) == -1 ) {
2335                                         during_slink = 1;
2336                                         break;
2337                                 }
2338                         }
2339                 }
2340
2341                 disable_where_scriptlink( (short)(during_slink - 1) );
2342
2343                 /* cleanup bylink flag and clear link so PyObject
2344                  * can be released 
2345                  */
2346                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
2347                 PyDict_SetItemString( g_blenderdict, "link", Py_None );
2348                 EXPP_dict_set_item_str( g_blenderdict, "event", PyString_FromString( "" ) );
2349
2350                 PyGILState_Release(gilstate);
2351         }
2352 }
2353
2354
2355 /* SPACE HANDLERS */
2356
2357 /* These are special script links that can be assigned to ScrArea's to
2358  * (EVENT type) receive events sent to a given space (and use or ignore them) or
2359  * (DRAW type) be called after the space is drawn, to draw anything on top of
2360  * the space area. */
2361
2362 /* How to add space handlers to other spaces:
2363  * - add the space event defines to DNA_scriptlink_types.h, as done for
2364  *   3d view: SPACEHANDLER_VIEW3D_EVENT, for example;
2365  * - add the new defines to Blender.SpaceHandler dictionary in Blender.c;
2366  * - check space.c for how to call the event handlers;
2367  * - check drawview.c for how to call the draw handlers;
2368  * - check header_view3d.c for how to add the "Space Handler Scripts" menu.
2369  * Note: DRAW handlers should be called with 'event = 0', chech drawview.c */
2370
2371 int BPY_has_spacehandler(Text *text, ScrArea *sa)
2372 {
2373         ScriptLink *slink;
2374         int index;
2375
2376         if (!sa || !text) return 0;
2377
2378         slink = &sa->scriptlink;
2379
2380         for (index = 0; index < slink->totscript; index++) {
2381                 if (slink->scripts[index] && (slink->scripts[index] == (ID *)text))
2382                         return 1;
2383         }
2384
2385         return 0;       
2386 }
2387
2388 int BPY_is_spacehandler(Text *text, char spacetype)
2389 {
2390         TextLine *tline = text->lines.first;
2391         unsigned short type = 0;
2392
2393         if (tline && (tline->len > 10)) {
2394                 char *line = tline->line;
2395
2396                 /* Expected format: # SPACEHANDLER.SPACE.TYPE
2397                  * Ex: # SPACEHANDLER.VIEW3D.DRAW
2398                  * The actual checks are forgiving, so slight variations also work. */
2399                 if (line && line[0] == '#' && strstr(line, "HANDLER")) {
2400                         line++; /* skip '#' */
2401
2402                         /* only done for 3D View right now, trivial to add for others: */
2403                         switch (spacetype) {
2404                                 case SPACE_VIEW3D:
2405                                         if (strstr(line, "3D")) { /* VIEW3D, 3DVIEW */
2406                                                 if (strstr(line, "DRAW")) type = SPACEHANDLER_VIEW3D_DRAW;
2407                                                 else if (strstr(line, "EVENT")) type = SPACEHANDLER_VIEW3D_EVENT;
2408                                         }
2409                                         break;
2410                         }
2411                 }
2412         }
2413         return type; /* 0 if not a space handler */
2414 }
2415
2416 int BPY_del_spacehandler(Text *text, ScrArea *sa)
2417 {
2418         ScriptLink *slink;
2419         int i, j;
2420
2421         if (!sa || !text) return -1;
2422
2423         slink = &sa->scriptlink;
2424         if (slink->totscript < 1) return -1;
2425
2426         for (i = 0; i < slink->totscript; i++) {
2427                 if (text == (Text *)slink->scripts[i]) {
2428
2429                         for (j = i; j < slink->totscript - 1; j++) {
2430                                 slink->flag[j] = slink->flag[j+1];
2431                                 slink->scripts[j] = slink->scripts[j+1];
2432                         }
2433                         slink->totscript--;
2434                         /* like done in buttons_script.c we just free memory
2435                          * if all slinks have been removed -- less fragmentation,
2436                          * these should be quite small arrays */
2437                         if (slink->totscript == 0) {
2438                                 if (slink->scripts) MEM_freeN(slink->scripts);
2439                                 if (slink->flag) MEM_freeN(slink->flag);
2440                                 break;
2441                         }
2442                 }
2443         }
2444         return 0;
2445 }
2446
2447 int BPY_add_spacehandler(Text *text, ScrArea *sa, char spacetype)
2448 {
2449         unsigned short handlertype;
2450
2451         if (!sa || !text) return -1;
2452
2453         handlertype = (unsigned short)BPY_is_spacehandler(text, spacetype);
2454
2455         if (handlertype) {
2456                 ScriptLink *slink = &sa->scriptlink;
2457                 void *stmp, *ftmp;
2458                 unsigned short space_event = SPACEHANDLER_VIEW3D_EVENT;
2459
2460                 /* extend slink */
2461
2462                 stmp= slink->scripts;           
2463                 slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1),
2464                         "spacehandlerscripts");
2465         
2466                 ftmp= slink->flag;              
2467                 slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1),
2468                         "spacehandlerflags");
2469         
2470                 if (slink->totscript) {
2471                         memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript));
2472                         MEM_freeN(stmp);
2473
2474                         memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript));
2475                         MEM_freeN(ftmp);
2476                 }
2477
2478                 switch (spacetype) {
2479                         case SPACE_VIEW3D:
2480                                 if (handlertype == 1) space_event = SPACEHANDLER_VIEW3D_EVENT;
2481                                 else space_event = SPACEHANDLER_VIEW3D_DRAW;
2482                                 break;
2483                         default:
2484                                 break;
2485                 }
2486
2487                 slink->scripts[slink->totscript] = (ID *)text;
2488                 slink->flag[slink->totscript]= space_event;
2489
2490                 slink->totscript++;
2491                 slink->actscript = slink->totscript;
2492
2493         }
2494         return 0;
2495 }
2496
2497 int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
2498         short eventValue, unsigned short space_event )
2499 {
2500         ScriptLink *scriptlink;
2501         int retval = 0;
2502         PyGILState_STATE gilstate;
2503         
2504         if (!sa || !(G.f & G_DOSCRIPTLINKS)) return 0;
2505         
2506         scriptlink = &sa->scriptlink;
2507
2508         if (scriptlink->totscript > 0) {
2509                 PyObject *dict;
2510                 PyObject *ret;
2511                 int index, during_slink = during_scriptlink();
2512
2513                 /* invalid scriptlinks (new .blend was just loaded), return */
2514                 if (during_slink < 0) return 0;
2515
2516                 /* tell we're running a scriptlink.  The sum also tells if this script
2517                  * is running nested inside another.  Blender.Load needs this info to
2518                  * avoid trouble with invalid slink pointers.
2519                  * Update (test): allow EVENT space handlers to call file/image selectors,
2520                  * still disabled for DRAW space handlers: */
2521                 if (event == 0) { /* event = 0: DRAW space handler */
2522                         during_slink++;
2523                         disable_where_scriptlink( (short)during_slink );
2524                 }
2525                 
2526                 gilstate = PyGILState_Ensure();
2527                 
2528                 if( !setup_armature_weakrefs()){
2529                         printf("Oops - weakref dict, this is a bug\n");
2530                         PyGILState_Release(gilstate);
2531                         return 0;
2532                 }
2533                 
2534                 /* set globals in Blender module to identify space handler scriptlink */
2535                 PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
2536                 /* unlike normal scriptlinks, here Blender.link is int (space event type) */
2537                 EXPP_dict_set_item_str(g_blenderdict, "link", PyInt_FromLong(space_event));
2538                 /* note: DRAW space_events set event and val to 0 */
2539                 EXPP_dict_set_item_str(g_blenderdict, "event", PyInt_FromLong(event));
2540                 EXPP_dict_set_item_str(g_blenderdict, "eventValue", PyInt_FromLong(eventValue));
2541                 /* now run all assigned space handlers for this space and space_event */
2542                 for( index = 0; index < scriptlink->totscript; index++ ) {
2543                         
2544                         /* for DRAW handlers: */
2545                         if (event == 0) {
2546                                 glPushAttrib(GL_ALL_ATTRIB_BITS);
2547                                 glMatrixMode(GL_PROJECTION);
2548                                 glPushMatrix();
2549                                 glMatrixMode(GL_MODELVIEW);
2550                                 glPushMatrix();
2551                         }
2552                         
2553                         if( ( scriptlink->flag[index] == space_event ) &&
2554                             ( scriptlink->scripts[index] != NULL ) ) {
2555                                 dict = CreateGlobalDictionary();
2556                                 ret = RunPython( ( Text * ) scriptlink->scripts[index], dict );
2557                                 ReleaseGlobalDictionary( dict );
2558
2559                                 if (!ret) { /* Failed execution of the script */
2560                                         BPY_Err_Handle( scriptlink->scripts[index]->name+2 );
2561                                 } else {
2562                                         Py_DECREF(ret);
2563
2564                                         /* an EVENT type (event != 0) script can either accept an event or
2565                                          * ignore it:
2566                                          * if the script sets Blender.event to None it accepted it;
2567                                          * otherwise the space's event handling callback that called us
2568                                          * can go on processing the event */
2569                                         if (event && (PyDict_GetItemString(g_blenderdict,"event") == Py_None))
2570                                                 retval = 1; /* event was swallowed */
2571                                 }
2572                                 
2573                                 /* If a scriptlink has just loaded a new .blend file, the
2574                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
2575                                  * so we stop here. */
2576                                 if( during_scriptlink(  ) == -1 ) {
2577                                         during_slink = 1;
2578                                         if (event == 0) glPopAttrib();
2579                                         break;
2580                                 }
2581                         }
2582                         
2583                         /* for DRAW handlers: */
2584                         if (event == 0) {
2585                                 glMatrixMode(GL_PROJECTION);
2586                                 glPopMatrix();
2587                                 glMatrixMode(GL_MODELVIEW);
2588                                 glPopMatrix();
2589                                 glPopAttrib();
2590                                 disable_where_scriptlink( (short)(during_slink - 1) );
2591                         }
2592                 
2593                 }
2594                 
2595                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
2596                 PyDict_SetItemString(g_blenderdict, "link", Py_None );
2597                 EXPP_dict_set_item_str(g_blenderdict, "event", PyString_FromString(""));
2598                 
2599                 PyGILState_Release(gilstate);
2600         }
2601         
2602         /* retval:
2603          * space_event is of type EVENT:
2604          * 0 - event was returned,
2605          * 1 - event was processed;
2606          * space_event is of type DRAW:
2607          * 0 always */
2608
2609         return retval;
2610 }
2611
2612 /*****************************************************************************
2613 * Description:  
2614 * Notes:
2615 *****************************************************************************/
2616 void BPY_free_scriptlink( struct ScriptLink *slink )
2617 {
2618         if( slink->totscript ) {
2619                 if( slink->flag ) {
2620                         MEM_freeN( slink->flag );
2621                         slink->flag= NULL;
2622                 }
2623                 if( slink->scripts ) {
2624                         MEM_freeN( slink->scripts );
2625                         slink->scripts= NULL;
2626                 }
2627         }
2628
2629         return;
2630 }
2631
2632 static int CheckAllSpaceHandlers(Text *text)
2633 {
2634         bScreen *screen;
2635         ScrArea *sa;
2636         ScriptLink *slink;
2637         int fixed = 0;
2638
2639         for (screen = G.main->screen.first; screen; screen = screen->id.next) {
2640                 for (sa = screen->areabase.first; sa; sa = sa->next) {
2641                         slink = &sa->scriptlink;
2642                         if (!slink->totscript) continue;
2643                         if (BPY_del_spacehandler(text, sa) == 0) fixed++;
2644                 }
2645         }
2646         return fixed;
2647 }
2648
2649 static int CheckAllScriptsFromList( ListBase * list, Text * text )
2650 {
2651         ID *id;
2652         ScriptLink *scriptlink;
2653         int index;
2654         int fixed = 0;
2655
2656         id = list->first;
2657
2658         while( id != NULL ) {
2659                 scriptlink = ID_getScriptlink( id );
2660                 if( scriptlink && scriptlink->totscript ) {
2661                         for( index = 0; index < scriptlink->totscript; index++) {
2662                                 if ((Text *)scriptlink->scripts[index] == text) {
2663                                         scriptlink->scripts[index] = NULL;
2664                                         fixed++;
2665                                 }
2666                         }
2667                 }
2668                 id = id->next;
2669         }
2670
2671         return fixed;
2672 }
2673
2674 /* When a Text is deleted, we need to unlink it from eventual scriptlinks */
2675 int BPY_check_all_scriptlinks( Text * text )
2676 {
2677         int fixed = 0;
2678         fixed += CheckAllScriptsFromList( &( G.main->object ), text );
2679         fixed += CheckAllScriptsFromList( &( G.main->lamp ), text );
2680         fixed += CheckAllScriptsFromList( &( G.main->camera ), text );
2681         fixed += CheckAllScriptsFromList( &( G.main->mat ), text );
2682         fixed += CheckAllScriptsFromList( &( G.main->world ), text );
2683         fixed += CheckAllScriptsFromList( &( G.main->scene ), text );
2684         fixed += CheckAllSpaceHandlers(text);
2685
2686         return fixed;
2687 }
2688
2689 /*****************************************************************************
2690 * Description: 
2691 * Notes:
2692 *****************************************************************************/
2693 void BPY_copy_scriptlink( struct ScriptLink *scriptlink )
2694 {
2695         void *tmp;
2696
2697         if( scriptlink->totscript ) {
2698
2699                 tmp = scriptlink->scripts;
2700                 scriptlink->scripts =
2701                         MEM_mallocN( sizeof( ID * ) * scriptlink->totscript,
2702                                      "scriptlistL" );
2703                 memcpy( scriptlink->scripts, tmp,
2704                         sizeof( ID * ) * scriptlink->totscript );
2705
2706                 tmp = scriptlink->flag;
2707                 scriptlink->flag =
2708                         MEM_mallocN( sizeof( short ) * scriptlink->totscript,
2709                                      "scriptlistF" );
2710                 memcpy( scriptlink->flag, tmp,
2711                         sizeof( short ) * scriptlink->totscript );
2712         }
2713
2714         return;
2715 }
2716
2717 /****************************************************************************
2718 * Description:
2719 * Notes:                Not implemented yet
2720 *****************************************************************************/
2721 int BPY_call_importloader( char *name )
2722 {                       /* XXX Should this function go away from Blender? */
2723         printf( "In BPY_call_importloader(name=%s)\n", name );
2724         return ( 0 );
2725 }
2726
2727 /*****************************************************************************
2728 * Private functions
2729 *****************************************************************************/
2730
2731 /*****************************************************************************
2732 * Description: This function executes the python script passed by text. 
2733 *               The Python dictionary containing global variables needs to
2734 *               be passed in globaldict.
2735 *               NOTE: Make sure BPY_Err_Handle() runs if this returns NULL
2736 *               otherwise pointers can be left in sys.last_traceback that become invalid.
2737 *****************************************************************************/
2738 static PyObject *RunPython( Text * text, PyObject * globaldict )
2739 {
2740         char *buf = NULL;
2741
2742 /* The script text is compiled to Python bytecode and saved at text->compiled
2743  * to speed-up execution if the user executes the script multiple times */
2744
2745         if( !text->compiled ) { /* if it wasn't already compiled, do it now */
2746                 buf = txt_to_buf( text );
2747
2748                 text->compiled =
2749                         Py_CompileString( buf, text->id.name+2, Py_file_input );
2750
2751                 MEM_freeN( buf );
2752
2753                 if( PyErr_Occurred(  ) ) {
2754                         BPY_free_compiled_text( text );
2755                         return NULL;
2756                 }
2757
2758         }
2759
2760         return PyEval_EvalCode( text->compiled, globaldict, globaldict );
2761 }
2762
2763 /*****************************************************************************
2764 * Description: This function creates a new Python dictionary object.
2765 *****************************************************************************/
2766 static PyObject *CreateGlobalDictionary( void )
2767 {
2768         PyObject *dict = PyDict_New(  );
2769
2770         PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
2771         EXPP_dict_set_item_str( dict, "__name__",
2772                               PyString_FromString( "__main__" ) );
2773
2774         return dict;
2775 }
2776
2777 /*****************************************************************************
2778 * Description: This function deletes a given Python dictionary object.
2779 *****************************************************************************/
2780 static void ReleaseGlobalDictionary( PyObject * dict )
2781 {
2782         PyDict_Clear( dict );
2783         Py_DECREF( dict );      /* Release dictionary. */
2784
2785         return;
2786 }
2787
2788 /***************************************************************************
2789 * Description: This function runs all scripts (if any) present in the
2790 *               list argument. The event by which the function has been 
2791 *               called, is passed in the event argument.
2792 *****************************************************************************/
2793 static void DoAllScriptsFromList( ListBase * list, short event )
2794 {
2795         ID *id;
2796
2797         id = list->first;
2798
2799         while( id != NULL ) {
2800                 BPY_do_pyscript( id, event );
2801                 id = id->next;
2802         }
2803
2804         return;
2805 }
2806
2807 static PyObject *importText( char *name )
2808 {
2809         Text *text;
2810         char txtname[22]; /* 21+NULL */
2811         char *buf = NULL;
2812         int namelen = strlen( name );
2813         
2814         if (namelen>21-3) return NULL; /* we know this cant be importable, the name is too long for blender! */
2815         
2816         memcpy( txtname, name, namelen );
2817         memcpy( &txtname[namelen], ".py", 4 );
2818
2819         for(text = G.main->text.first; text; text = text->id.next) {
2820                 if( !strcmp( txtname, text->id.name+2 ) )
2821                         break;
2822         }
2823
2824         if( !text )
2825                 return NULL;
2826
2827         if( !text->compiled ) {
2828                 buf = txt_to_buf( text );
2829                 text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
2830                 MEM_freeN( buf );
2831
2832                 if( PyErr_Occurred(  ) ) {
2833                         PyErr_Print(  );
2834                         BPY_free_compiled_text( text );
2835                         return NULL;
2836                 }
2837         }
2838
2839         return PyImport_ExecCodeModule( name, text->compiled );
2840 }
2841
2842 static PyMethodDef bimport[] = {
2843         {"blimport", blender_import, METH_VARARGS, "our own import"}
2844 };
2845
2846 static PyObject *blender_import( PyObject * self, PyObject * args )
2847 {
2848         PyObject *exception, *err, *tb;
2849         char *name;
2850         PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
2851         PyObject *m;
2852         //PyObject_Print(args, stderr, 0);
2853 #if (PY_VERSION_HEX >= 0x02060000)
2854         int dummy_val; /* what does this do?*/
2855         
2856         if( !PyArg_ParseTuple( args, "s|OOOi:bimport",
2857                                &name, &globals, &locals, &fromlist, &dummy_val) )
2858                 return NULL;
2859 #else
2860         if( !PyArg_ParseTuple( args, "s|OOO:bimport",
2861                                &name, &globals, &locals, &fromlist ) )
2862                 return NULL;
2863 #endif
2864         m = PyImport_ImportModuleEx( name, globals, locals, fromlist );
2865
2866         if( m )
2867                 return m;
2868         else
2869                 PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
2870
2871         m = importText( name );
2872         if( m ) {               /* found module, ignore above exception */
2873                 PyErr_Clear(  );
2874                 Py_XDECREF( exception );
2875                 Py_XDECREF( err );
2876                 Py_XDECREF( tb );
2877                 printf( "imported from text buffer...\n" );
2878         } else {
2879                 PyErr_Restore( exception, err, tb );
2880         }
2881         return m;
2882 }
2883
2884 static void init_ourImport( void )
2885 {
2886         PyObject *m, *d;
2887         PyObject *import = PyCFunction_New( bimport, NULL );
2888
2889         m = PyImport_AddModule( "__builtin__" );
2890         d = PyModule_GetDict( m );
2891         
2892         EXPP_dict_set_item_str( d, "__import__", import );
2893 }
2894
2895 /*
2896  * find in-memory module and recompile
2897  */
2898
2899 static PyObject *reimportText( PyObject *module )
2900 {
2901         Text *text;
2902         char *txtname;
2903         char *name;
2904         char *buf = NULL;
2905
2906         /* get name, filename from the module itself */
2907
2908         txtname = PyModule_GetFilename( module );
2909         name = PyModule_GetName( module );
2910         if( !txtname || !name)
2911                 return NULL;
2912
2913         /* look up the text object */
2914         text = ( Text * ) & ( G.main->text.first );
2915         while( text ) {
2916                 if( !strcmp( txtname, text->id.name+2 ) )
2917                         break;
2918                 text = text->id.next;
2919         }
2920
2921         /* uh-oh.... didn't find it */
2922         if( !text )
2923                 return NULL;
2924
2925         /* if previously compiled, free the object */
2926         /* (can't see how could be NULL, but check just in case) */ 
2927         if( text->compiled ){
2928                 Py_DECREF( (PyObject *)text->compiled );
2929         }
2930
2931         /* compile the buffer */
2932         buf = txt_to_buf( text );
2933         text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
2934         MEM_freeN( buf );
2935
2936         /* if compile failed.... return this error */
2937         if( PyErr_Occurred(  ) ) {
2938                 PyErr_Print(  );
2939                 BPY_free_compiled_text( text );
2940                 return NULL;
2941         }
2942
2943         /* make into a module */
2944         return PyImport_ExecCodeModule( name, text->compiled );
2945 }
2946
2947 /*
2948  * our reload() module, to handle reloading in-memory scripts
2949  */
2950
2951 static PyObject *blender_reload( PyObject * self, PyObject * args )
2952 {
2953         PyObject *exception, *err, *tb;
2954         PyObject *module = NULL;
2955         PyObject *newmodule = NULL;
2956
2957         /* check for a module arg */
2958         if( !PyArg_ParseTuple( args, "O:breload", &module ) )
2959                 return NULL;
2960
2961         /* try reimporting from file */
2962         newmodule = PyImport_ReloadModule( module );
2963         if( newmodule )
2964                 return newmodule;
2965
2966         /* no file, try importing from memory */
2967         PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
2968
2969         newmodule = reimportText( module );
2970         if( newmodule ) {               /* found module, ignore above exception */
2971                 PyErr_Clear(  );
2972                 Py_XDECREF( exception );
2973                 Py_XDECREF( err );
2974                 Py_XDECREF( tb );
2975         } else
2976                 PyErr_Restore( exception, err, tb );
2977
2978         return newmodule;
2979 }
2980
2981 static PyMethodDef breload[] = {
2982         {"blreload", blender_reload, METH_VARARGS, "our own reload"}
2983 };
2984
2985 static void init_ourReload( void )
2986 {
2987         PyObject *m, *d;
2988         PyObject *reload = PyCFunction_New( breload, NULL );
2989
2990         m = PyImport_AddModule( "__builtin__" );
2991         d = PyModule_GetDict( m );
2992         EXPP_dict_set_item_str( d, "reload", reload );
2993 }
2994
2995
2996 void BPY_scripts_clear_pyobjects( void )
2997 {
2998         Script *script;
2999         for (script=G.main->script.first; script; script=script->id.next) {
3000                 Py_XDECREF((PyObject *)script->py_draw);
3001                 Py_XDECREF((PyObject *)script->py_event);
3002                 Py_XDECREF((PyObject *)script->py_button);
3003                 Py_XDECREF((PyObject *)script->py_browsercallback);
3004                 Py_XDECREF((PyObject *)script->py_globaldict); 
3005                 SCRIPT_SET_NULL(script)
3006         }
3007 }
3008 void error_pyscript( void )
3009 {
3010         error("Python script error: check console");
3011 }