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