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