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