~diresu/blender/blender-command-port

« back to all changes in this revision

Viewing changes to source/blender/python/BPY_interface.c

  • Committer: theeth
  • Date: 2008-10-14 16:52:04 UTC
  • Revision ID: vcs-imports@canonical.com-20081014165204-r32w2gm6s0osvdhn
copy back trunk

Show diffs side-by-side

added added

removed removed

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