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