2
* $Id: BPY_interface.c 16894 2008-10-03 06:27:41Z campbellbarton $
4
* ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21
* All rights reserved.
23
* This is a new part of Blender.
25
* Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney,
26
* Chris Keith, Chris Want, Ken Hughes
28
* ***** END GPL LICENSE BLOCK *****
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() */
44
#include "BKE_constraint.h" /* for bConstraintOb */
45
#include "BKE_idprop.h"
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 */
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"
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 */
75
/*these next two are for pyconstraints*/
76
#include "api2_2x/IDProp.h"
77
#include "api2_2x/matrix.h"
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"
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.
92
/*#include "api2_2x/Registry.h" */
94
/* for pydrivers (ipo drivers defined by one-line Python expressions) */
95
PyObject *bpy_pydriver_Dict = NULL;
96
PyObject *bpy_orig_syspath_List = NULL;
100
* set up a weakref list for Armatures
101
* creates list in __main__ module dict
104
static int setup_armature_weakrefs()
107
PyObject *main_module;
108
char *list_name = ARM_WEAKREF_LIST_NAME;
110
main_module = PyImport_AddModule( "__main__");
112
PyObject *weakreflink;
113
maindict= PyModule_GetDict(main_module);
115
/* check if there is already a dict entry for the armature weakrefs,
116
* and delete if so before making another one */
118
weakreflink= PyDict_GetItemString(maindict,list_name);
119
if( weakreflink != NULL ) {
120
PyDict_DelItemString(maindict,list_name);
121
Py_XDECREF( weakreflink );
124
if (PyDict_SetItemString(maindict,
126
PyList_New(0)) == -1){
127
printf("Oops - setup_armature_weakrefs()\n");
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` */
139
static struct _inittab BPy_Inittab_Modules[] = {
140
{"Blender", M_Blender_Init},
145
/*************************************************************************
146
* Structure definitions
147
**************************************************************************/
148
#define FILENAME_LENGTH 24
150
typedef struct _ScriptError {
151
char filename[FILENAME_LENGTH];
155
/****************************************************************************
157
****************************************************************************/
158
ScriptError g_script_error;
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 );
173
static void BPY_Err_Handle( char *script_name );
174
static PyObject *traceback_getFilename( PyObject * tb );
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 )
182
PyThreadState *py_tstate = NULL;
183
static int argc_copy = 0;
184
static char **argv_copy = NULL;
185
int first_time = argc;
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) */
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" );
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.
206
/* print Python version
207
* Py_GetVersion() returns a ptr to a static string "9.9.9 (aaaa..."
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, ' ');
215
count = blank_ptr - version;
217
printf( "Compiled with Python version %.*s.\n", count, version );
221
//Initialize the TOP-LEVEL modules
222
PyImport_ExtendInittab(BPy_Inittab_Modules);
224
//Start the interpreter
227
PySys_SetArgv( argc_copy, argv_copy );
228
/* Initialize thread support (also acquires lock) */
229
PyEval_InitThreads();
231
//Overrides __import__
235
//init a global dictionary
236
g_blenderdict = NULL;
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);
246
/*****************************************************************************/
247
/* Description: This function will terminate the Python interpreter */
248
/*****************************************************************************/
249
void BPY_end_python( void )
251
Script *script = NULL;
252
Script *next_script = NULL;
254
PyGILState_Ensure(); /* finalizing, no need to grab the state */
256
if( bpy_registryDict ) {
257
Py_DECREF( bpy_registryDict );
258
bpy_registryDict = NULL;
261
if( bpy_pydriver_Dict ) {
262
Py_DECREF( bpy_pydriver_Dict );
263
bpy_pydriver_Dict = NULL;
266
if( bpy_orig_syspath_List ) {
267
Py_DECREF( bpy_orig_syspath_List );
268
bpy_orig_syspath_List = NULL;
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 );
280
BPyMenu_RemoveAllEntries( ); /* freeing bpymenu mem */
282
/* a script might've opened a .blend file but didn't close it, so: */
283
EXPP_Library_Close( );
288
void syspath_append( char *dirname )
290
PyObject *mod_sys= NULL, *dict= NULL, *path= NULL, *dir= NULL;
293
mod_sys = PyImport_ImportModule( "sys" ); /* new ref */
296
dict = PyModule_GetDict( mod_sys ); /* borrowed ref */
297
path = PyDict_GetItemString( dict, "path" ); /* borrowed ref */
298
if ( !PyList_Check( path ) ) {
302
/* cant get the sys module */
303
/* PyErr_Clear(); is called below */
307
dir = PyString_FromString( dirname );
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 */
314
if( (ok==0) || PyErr_Occurred( ) )
315
fprintf(stderr, "Warning: could import or build sys.path\n" );
319
Py_XDECREF( mod_sys );
322
void init_syspath( int first_time )
326
char execdir[FILE_MAXDIR]; /*defines from DNA_space_types.h */
330
mod = PyImport_ImportModule( "Blender.sys" );
333
d = PyModule_GetDict( mod );
334
EXPP_dict_set_item_str( d, "progname", PyString_FromString( bprogname ) );
337
printf( "Warning: could not set Blender.sys\n" );
341
progname = BLI_last_slash( bprogname ); /* looks for the last dir separator */
343
n = progname - bprogname;
345
strncpy( execdir, bprogname, n );
346
if( execdir[n - 1] == '.' )
347
n--; /*fix for when run as ./blender */
350
syspath_append( execdir ); /* append to module search path */
352
printf( "Warning: could not determine argv[0] path\n" );
356
attempt to import 'site' module as a check for valid
357
python install found.
360
printf("Checking for installed Python... "); /* appears after msg "Compiled with Python 2.x" */
361
mod = PyImport_ImportModule( "site" ); /* new ref */
366
} else { /* import 'site' failed */
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" );
377
* initialize the sys module
378
* set sys.executable to the Blender exe
381
mod = PyImport_ImportModule( "sys" ); /* new ref */
384
d = PyModule_GetDict( mod ); /* borrowed ref */
385
EXPP_dict_set_item_str( d, "executable", Py_BuildValue( "s", bprogname ) );
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);
393
bpy_orig_syspath_List = PyList_GetSlice(syspath, 0, PyList_Size(syspath));
399
printf("Warning: import of sys module failed\n");
403
void BPY_rebuild_syspath( void )
405
PyObject *mod, *dict, *syspath;
406
char dirpath[FILE_MAX];
408
PyGILState_STATE gilstate = PyGILState_Ensure();
410
mod = PyImport_ImportModule( "sys" );
412
printf("Warning: could not import python sys module. some modules may not import.\n");
414
PyGILState_Release(gilstate);
418
if (!bpy_orig_syspath_List) { /* should never happen */
419
printf("Warning: cant refresh python path, bpy_orig_syspath_List is NULL\n");
421
PyGILState_Release(gilstate);
425
dict = PyModule_GetDict( mod ); /* borrowed ref */
428
syspath = PyDict_GetItemString( dict, "path" ); /* borrowed ref */
429
PyList_SetSlice(syspath, 0, PyList_Size(syspath), bpy_orig_syspath_List);
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);
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
444
if (dirpath[upyslen-1] == '\\' || dirpath[upyslen-1] == '/') {
445
dirpath[upyslen-1] = '\0';
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);
455
sdir = bpy_gethome(1);
457
syspath_append(sdir);
458
BLI_make_file_string("/", dirpath, sdir, "bpymodules");
459
if (BLI_exists(dirpath)) syspath_append(dirpath);
463
PyGILState_Release(gilstate);
466
int BPY_path_update( void )
468
BPyMenu_RemoveAllEntries(); /* free old data */
469
BPY_rebuild_syspath();
470
if (BPyMenu_Init(1) == -1) { /* re-eval scripts registration in menus */
476
/****************************************************************************
477
* Description: This function finishes Python initialization in Blender.
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 )
487
PyGILState_STATE gilstate = PyGILState_Ensure();
489
BPY_rebuild_syspath();
490
BPyMenu_Init( 0 ); /* get dynamic menus (registered scripts) data */
492
PyGILState_Release(gilstate);
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 )
501
return g_script_error.lineno;
504
/*****************************************************************************/
505
/* Description: This function will return the filename of the python script. */
506
/*****************************************************************************/
507
const char *BPY_Err_getFilename( void )
509
return g_script_error.filename;
512
/*****************************************************************************/
513
/* Description: Return PyString filename from a traceback object */
514
/*****************************************************************************/
515
static PyObject *traceback_getFilename( PyObject * tb )
519
/* co_filename is in f_code, which is in tb_frame, which is in tb */
521
v = PyObject_GetAttrString( tb, "tb_frame" );
524
v = PyObject_GetAttrString( v, "f_code" );
527
v = PyObject_GetAttrString( v, "co_filename" );
532
else return PyString_FromString("unknown");
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 )
541
PyObject *exception, *err, *tb, *v;
544
printf( "Error: script has NULL name\n" );
548
PyErr_Fetch( &exception, &err, &tb );
550
if (!script_name) script_name = "untitled";
551
//if( !exception && !tb ) {
552
// printf( "FATAL: spurious exception\n" );
556
strcpy( g_script_error.filename, script_name );
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! */
564
v = PyObject_GetAttrString( err, "lineno" );
566
g_script_error.lineno = PyInt_AsLong( v );
569
g_script_error.lineno = -1;
571
/* this avoids an abort in Python 2.3's garbage collecting: */
575
PyErr_NormalizeException( &exception, &err, &tb );
576
PyErr_Restore( exception, err, tb ); /* takes away reference! */
578
tb = PySys_GetObject( "last_traceback" );
581
printf( "\nCan't get traceback\n" );
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."'
595
v = PyObject_GetAttrString( tb, "tb_next" );
597
if( !v || v == Py_None ||
598
strcmp(PyString_AsString(traceback_getFilename(v)), script_name)) {
606
v = PyObject_GetAttrString( tb, "tb_lineno" );
608
g_script_error.lineno = PyInt_AsLong(v);
611
v = traceback_getFilename( tb );
613
strncpy( g_script_error.filename, PyString_AsString( v ),
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 )
630
PyObject *py_dict, *py_result;
633
Script *script = G.main->script.first;
634
PyGILState_STATE gilstate;
639
/* check if this text is already running */
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: */
646
newspace( curarea, SPACE_SCRIPT );
647
sc = curarea->spacedata.first;
652
script = script->id.next;
655
/* Create a new script structure and initialize it: */
656
script = alloc_libblock( &G.main->script, ID_SCRIPT, text->id.name+2 );
659
printf( "couldn't allocate memory for Script struct!" );
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.
667
BLI_strncpy( textname, text->id.name+2, 21 );
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();
678
py_dict = CreateGlobalDictionary( );
680
if( !setup_armature_weakrefs()){
681
printf("Oops - weakref dict\n");
682
PyGILState_Release(gilstate);
686
script->py_globaldict = py_dict;
688
info = ( BPy_constant * ) PyConstant_New( );
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 );
698
py_result = RunPython( text, py_dict ); /* Run the script */
700
if( !py_result ) { /* Failed execution of the script */
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);
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 );
718
PyGILState_Release(gilstate);
720
return 1; /* normal return */
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
727
****************************************************************************/
728
void BPY_run_python_script( const char *fn )
730
char filename[FILE_MAXDIR + FILE_MAXFILE];
732
int is_blender_text = 0;
734
BLI_strncpy(filename, fn, FILE_MAXDIR + FILE_MAXFILE);
736
if (!BLI_exists(filename))
737
BLI_convertstringcwd(filename);
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
744
text = G.main->text.first;
747
if (!strcmp(fn, text->id.name + 2)) break;
748
text = text->id.next;
752
printf("\nError: no such file or Blender text -- %s.\n", fn);
755
else is_blender_text = 1; /* fn is already a Blender Text */
759
/* use filename here since we know it exists,
760
* 'fn' may have been a relative path
762
text = add_text(filename);
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. */
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());
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);
789
int BPY_run_script(Script *script)
791
PyObject *py_dict, *py_res, *pyarg;
795
PyGILState_STATE gilstate = PyGILState_Ensure();
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];
802
char *bpyhome = bpy_gethome(1);
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);
811
if (BLI_exists(fpath)) {
812
strncpy(script->scriptname, fpath, sizeof(script->scriptname));
814
bpyhome = NULL; /* a bit dodgy, this is so the line below runs */
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));
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) {
835
Py_INCREF( Py_None );
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);
845
if( script->scriptarg[0] == '\0' ) { /* no submenus */
846
Py_INCREF( Py_None );
849
pyarg = PyString_FromString( script->scriptarg );
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;
860
py_dict = CreateGlobalDictionary( );
862
script->py_globaldict = py_dict;
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);
872
info = ( BPy_constant * ) PyConstant_New( );
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 );
882
py_res = RunPython( text, py_dict );
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 );
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
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 );
901
PyGILState_Release(gilstate);
905
script->flags &= ~SCRIPT_RUNNING;
907
if( !script->flags ) {
908
ReleaseGlobalDictionary( py_dict );
909
script->py_globaldict = NULL;
910
free_libblock( &G.main->script, script );
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.*/
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. */
925
PyGILState_Release(gilstate);
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 )
939
pym = BPyMenu_GetEntry( menutype, ( short ) event );
940
return BPY_menu_invoke( pym, menutype );
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 )
952
pym = BPyMenu_GetEntry( menutype, 0 );
955
if ( pym->key && pym->key == key && pym->qual == qual ) {
956
return BPY_menu_invoke( pym, menutype );
964
/****************************************************************************
965
* Description: This function executes the script described by a menu item.
966
*****************************************************************************/
967
int BPY_menu_invoke( BPyMenu *pym, short menutype )
972
Script *script = NULL;
974
PyGILState_STATE gilstate;
975
char filestr[FILE_MAX];
980
gilstate = PyGILState_Ensure();
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,
987
/* if there are submenus, let the user choose one from a pupmenu that we
989
pysm = pym->submenus;
994
pupstr = BPyMenu_CreatePupmenuStr( pym, menutype );
997
arg = pupmenu( pupstr );
1005
PyGILState_Release(gilstate);
1011
if( pym->dir ) { /* script is in U.pythondir */
1012
char upythondir[FILE_MAX];
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 );
1019
else { /* script is in default scripts dir */
1020
char *scriptsdir = bpy_gethome(1);
1023
printf("Error loading script: can't find default scripts dir!");
1024
PyGILState_Release(gilstate);
1028
BLI_make_file_string( "/", filestr, scriptsdir, pym->filename );
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';
1040
/* Create a new script structure and initialize it: */
1041
script = alloc_libblock( &G.main->script, ID_SCRIPT, scriptname );
1044
printf( "couldn't allocate memory for Script struct!" );
1045
PyGILState_Release(gilstate);
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 ) {
1054
case PYMENU_IMPORT: /* first 4 were handled in header_info.c */
1058
case PYMENU_WIZARDS:
1059
case PYMENU_SCRIPTTEMPLATE:
1060
case PYMENU_TEXTPLUGIN:
1061
case PYMENU_MESHFACEKEY:
1065
if( curarea->spacetype != SPACE_SCRIPT ) {
1068
sa = find_biggest_area_of_type( SPACE_BUTS );
1070
if( ( 1.5 * sa->winx ) < sa->winy )
1071
sa = NULL; /* too narrow? */
1075
sa = find_biggest_area_of_type( SPACE_SCRIPT );
1077
sa = find_biggest_area_of_type( SPACE_TEXT );
1079
sa = find_biggest_area_of_type( SPACE_IMAGE ); /* group UV */
1081
sa = find_biggest_area_of_type( SPACE_VIEW3D );
1084
sa = find_biggest_area( );
1086
areawinset( sa->win );
1091
strncpy(script->scriptname, filestr, sizeof(script->scriptname));
1092
if (argstr!=NULL && argstr[0] != '\0')
1093
strncpy(script->scriptarg, argstr, sizeof(script->scriptarg));
1095
ret = BPY_run_script(script);
1097
return 1; /* normal return */
1100
/*****************************************************************************
1103
*****************************************************************************/
1104
void BPY_free_compiled_text( struct Text *text )
1106
if( text->compiled ) {
1107
Py_DECREF( ( PyObject * ) text->compiled );
1108
text->compiled = NULL;
1112
/*****************************************************************************
1113
* Description: This function frees a finished (flags == 0) script.
1114
*****************************************************************************/
1115
void BPY_free_finished_script( Script * script )
1117
PyGILState_STATE gilstate;
1122
gilstate = PyGILState_Ensure();
1124
if( PyErr_Occurred( ) ) { /* if script ended after filesel */
1125
PyErr_Print( ); /* eventual errors are handled now */
1129
PyGILState_Release(gilstate);
1131
free_libblock( &G.main->script, script );
1135
static void unlink_script( Script * script )
1136
{ /* copied from unlink_text in drawtext.c */
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;
1147
if( sc->script == script ) {
1150
if( sc == area->spacedata.first ) {
1151
scrarea_queue_redraw( area );
1155
BPy_Set_DrawButtonsList(sc->but_refs);
1156
BPy_Free_DrawButtonsList();
1157
sc->but_refs = NULL;
1166
/* This is called from free_libblock( &G.main->script, script ); */
1167
void BPY_clear_script( Script * script )
1170
PyGILState_STATE gilstate;
1175
gilstate = PyGILState_Ensure();
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);
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';
1195
dict = script->py_globaldict;
1198
PyDict_Clear( dict );
1199
Py_DECREF( dict ); /* Release dictionary. */
1200
script->py_globaldict = NULL;
1203
PyGILState_Release(gilstate);
1205
unlink_script( script );
1210
/* PyDrivers are Ipo Drivers governed by expressions written in Python.
1211
* Expressions here are one-liners that evaluate to a float value. */
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)
1219
if (bpy_pydriver_Dict) return -1;
1224
bpy_pydriver_Dict = d;
1226
/* import some modules: builtins, Blender, math, Blender.noise */
1228
PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1230
mod = PyImport_ImportModule("Blender");
1232
PyDict_SetItemString(d, "Blender", mod);
1233
PyDict_SetItemString(d, "b", mod);
1239
mod = PyImport_ImportModule("math");
1241
PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
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);
1249
mod = PyImport_ImportModule("Blender.Noise");
1251
PyDict_SetItemString(d, "noise", mod);
1252
PyDict_SetItemString(d, "n", mod);
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() */
1263
PyDict_SetItemString(d, "pydrivers", mod);
1264
PyDict_SetItemString(d, "p", mod);
1270
/* short aliases for some Get() functions: */
1272
/* ob(obname) == Blender.Object.Get(obname) */
1273
mod = PyImport_ImportModule("Blender.Object");
1275
PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1278
PyDict_SetItemString(d, "ob", fcn);
1285
/* TODO - change these */
1286
/* me(meshname) == Blender.Mesh.Get(meshname) */
1287
mod = PyImport_ImportModule("Blender.Mesh");
1289
PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1292
PyDict_SetItemString(d, "me", fcn);
1299
/* ma(matname) == Blender.Material.Get(matname) */
1300
mod = PyImport_ImportModule("Blender.Material");
1302
PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1305
PyDict_SetItemString(d, "ma", fcn);
1315
/* error return function for BPY_eval_pydriver */
1316
static float pydriver_error(IpoDriver *driver) {
1318
if (bpy_pydriver_oblist)
1319
bpy_pydriver_freeList();
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;
1327
driver->flag |= IPO_DRIVER_FLAG_INVALID; /* py expression failed */
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);
1332
fprintf(stderr, "\nError in Ipo Driver: No Object\nThis is the failed Python expression:\n'%s'\n\n", driver->name);
1340
/********PyConstraints*********/
1342
/* This function checks whether a text-buffer is a PyConstraint candidate.
1343
* It uses simple text parsing that could be easily confused!
1345
int BPY_is_pyconstraint(Text *text)
1347
TextLine *tline = text->lines.first;
1349
if (tline && (tline->len > 10)) {
1350
char *line = tline->line;
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;
1359
/* This function frees links from pyconstraints to a given text-buffer.
1360
* Used when a text-buffer is unlinked!
1362
void BPY_free_pyconstraint_links(Text *text)
1368
/*check all pyconstraints*/
1369
for (ob=G.main->object.first; ob; ob=ob->id.next) {
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;
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;
1393
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
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.
1402
void BPY_pyconstraint_update(Object *owner, bConstraint *con)
1404
bPythonConstraint *data= con->data;
1407
/* script does exist. it is assumed that this is a valid pyconstraint script */
1409
PyObject *retval, *gval;
1410
PyGILState_STATE gilstate;
1413
/* clear the relevant flags first */
1416
gilstate = PyGILState_Ensure();
1418
/* populate globals dictionary */
1419
globals = CreateGlobalDictionary();
1420
retval = RunPython(data->text, globals);
1422
if (retval == NULL) {
1423
BPY_Err_Handle(data->text->id.name);
1424
ReleaseGlobalDictionary(globals);
1425
data->flag |= PYCON_SCRIPTERROR;
1426
PyGILState_Release(gilstate);
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;
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...
1443
data->flag |= PYCON_USETARGETS;
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);
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);
1463
/* validate targets */
1464
con->flag &= ~CONSTRAINT_DISABLE;
1465
for (ct= data->targets.first; ct; ct= ct->next) {
1466
if (!exist_object(ct->tar)) {
1468
con->flag |= CONSTRAINT_DISABLE;
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;
1481
ReleaseGlobalDictionary(globals);
1483
PyGILState_Release(gilstate);
1488
/* NUM_TARGETS is not defined or equals 0 */
1489
ReleaseGlobalDictionary(globals);
1491
/* free all targets */
1492
BLI_freelistN(&data->targets);
1494
data->flag &= ~PYCON_USETARGETS;
1496
PyGILState_Release(gilstate);
1502
/* no script, so clear any settings/data now */
1505
con->flag &= ~CONSTRAINT_DISABLE;
1507
BLI_freelistN(&data->targets);
1509
/* supposedly this should still leave the base struct... */
1510
IDP_FreeProperty(data->prop);
1514
/* PyConstraints Evaluation Function (only called from evaluate_constraint)
1515
* This function is responsible for modifying the ownermat that it is passed.
1517
void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase *targets)
1519
PyObject *srcmat, *tarmat, *tarmats, *idprop;
1522
PyObject *pyargs, *retval;
1523
bConstraintTarget *ct;
1524
MatrixObject *retmat;
1525
int row, col, index;
1526
PyGILState_STATE gilstate;
1528
if (!con->text) return;
1529
if (con->flag & PYCON_SCRIPTERROR) return;
1531
gilstate = PyGILState_Ensure();
1533
globals = CreateGlobalDictionary();
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
1540
srcmat = newMatrixObject((float *)cob->matrix, 4, 4, Py_NEW);
1541
idprop = BPy_Wrap_IDProperty(NULL, con->prop, NULL);
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);
1549
if (!setup_armature_weakrefs()) {
1550
fprintf(stderr, "Oops - weakref dict setup\n");
1551
PyGILState_Release(gilstate);
1556
retval = RunPython(con->text, globals);
1558
if (retval == NULL) {
1559
BPY_Err_Handle(con->text->id.name);
1560
con->flag |= PYCON_SCRIPTERROR;
1562
/* free temp objects */
1565
Py_XDECREF(tarmats);
1567
ReleaseGlobalDictionary(globals);
1569
PyGILState_Release(gilstate);
1574
if (retval) {Py_XDECREF( retval );}
1577
gval = PyDict_GetItemString(globals, "doConstraint");
1579
printf("ERROR: no doConstraint function in constraint!\n");
1581
/* free temp objects */
1584
Py_XDECREF(tarmats);
1586
ReleaseGlobalDictionary(globals);
1588
PyGILState_Release(gilstate);
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);
1600
printf("ERROR: doConstraint is supposed to be a function!\n");
1601
con->flag |= PYCON_SCRIPTERROR;
1605
Py_XDECREF(tarmats);
1607
ReleaseGlobalDictionary(globals);
1609
PyGILState_Release(gilstate);
1615
BPY_Err_Handle(con->text->id.name);
1616
con->flag |= PYCON_SCRIPTERROR;
1618
/* free temp objects */
1621
Py_XDECREF(tarmats);
1623
ReleaseGlobalDictionary(globals);
1625
PyGILState_Release(gilstate);
1631
if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1632
printf("Error in PyConstraint - doConstraint: Function not returning a matrix!\n");
1633
con->flag |= PYCON_SCRIPTERROR;
1637
Py_XDECREF(tarmats);
1640
ReleaseGlobalDictionary(globals);
1642
PyGILState_Release(gilstate);
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;
1654
Py_XDECREF(tarmats);
1657
ReleaseGlobalDictionary(globals);
1659
PyGILState_Release(gilstate);
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];
1671
/* free temp objects */
1674
Py_XDECREF(tarmats);
1678
ReleaseGlobalDictionary(globals);
1680
PyGILState_Release(gilstate);
1683
/* This evaluates the target matrix for each target the PyConstraint uses.
1684
* NOTE: it only does one target at a time!
1686
void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
1688
PyObject *tar, *subtar;
1689
PyObject *tarmat, *idprop;
1692
PyObject *pyargs, *retval;
1693
MatrixObject *retmat;
1695
PyGILState_STATE gilstate;
1697
if (!con->text) return;
1698
if (con->flag & PYCON_SCRIPTERROR) return;
1701
gilstate = PyGILState_Ensure();
1703
globals = CreateGlobalDictionary();
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);
1712
subtar = PyString_FromString(ct->subtarget);
1714
tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1715
idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1717
if (!setup_armature_weakrefs()) {
1718
fprintf(stderr, "Oops - weakref dict setup\n");
1719
PyGILState_Release(gilstate);
1723
retval = RunPython(con->text, globals);
1725
if (retval == NULL) {
1726
BPY_Err_Handle(con->text->id.name);
1727
con->flag |= PYCON_SCRIPTERROR;
1729
/* free temp objects */
1735
ReleaseGlobalDictionary(globals);
1737
PyGILState_Release(gilstate);
1745
/* try to find doTarget function to set the target matrix */
1746
gval = PyDict_GetItemString(globals, "doTarget");
1748
/* free temp objects */
1754
ReleaseGlobalDictionary(globals);
1756
PyGILState_Release(gilstate);
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);
1768
printf("ERROR: doTarget is supposed to be a function!\n");
1769
con->flag |= PYCON_SCRIPTERROR;
1776
ReleaseGlobalDictionary(globals);
1778
PyGILState_Release(gilstate);
1784
BPY_Err_Handle(con->text->id.name);
1785
con->flag |= PYCON_SCRIPTERROR;
1788
/* free temp objects */
1794
ReleaseGlobalDictionary(globals);
1796
PyGILState_Release(gilstate);
1801
if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1802
con->flag |= PYCON_SCRIPTERROR;
1810
ReleaseGlobalDictionary(globals);
1812
PyGILState_Release(gilstate);
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;
1828
ReleaseGlobalDictionary(globals);
1830
PyGILState_Release(gilstate);
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];
1842
/* free temp objects */
1850
ReleaseGlobalDictionary(globals);
1852
PyGILState_Release(gilstate);
1855
/* This draws+handles the user-defined interface for editing pyconstraints idprops */
1856
void BPY_pyconstraint_settings(void *arg1, void *arg2)
1858
bPythonConstraint *con= (bPythonConstraint *)arg1;
1863
PyGILState_STATE gilstate;
1865
if (!con->text) return;
1866
if (con->flag & PYCON_SCRIPTERROR) return;
1868
gilstate = PyGILState_Ensure();
1870
globals = CreateGlobalDictionary();
1872
idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1874
retval = RunPython(con->text, globals);
1876
if (retval == NULL) {
1877
BPY_Err_Handle(con->text->id.name);
1878
ReleaseGlobalDictionary(globals);
1879
con->flag |= PYCON_SCRIPTERROR;
1881
/* free temp objects */
1884
PyGILState_Release(gilstate);
1889
if (retval) {Py_XDECREF( retval );}
1892
gval = PyDict_GetItemString(globals, "getSettings");
1894
printf("ERROR: no getSettings function in constraint!\n");
1896
/* free temp objects */
1897
ReleaseGlobalDictionary( globals );
1900
PyGILState_Release(gilstate);
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);
1910
printf("ERROR: getSettings is supposed to be a function!\n");
1911
ReleaseGlobalDictionary( globals );
1915
PyGILState_Release(gilstate);
1921
BPY_Err_Handle(con->text->id.name);
1922
con->flag |= PYCON_SCRIPTERROR;
1924
/* free temp objects */
1925
ReleaseGlobalDictionary(globals);
1928
PyGILState_Release(gilstate);
1934
ReleaseGlobalDictionary(globals);
1936
/* free temp objects */
1940
PyGILState_Release(gilstate);
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)
1952
PyGILState_STATE gilstate = PyGILState_Ensure();
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;
1960
PyGILState_Release(gilstate);
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)
1970
/*if (!driver || !driver->ob || driver->name[0] == '\0')
1975
/* clear the flag that marks invalid python expressions */
1976
driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
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);
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);
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);
1991
bpy_pydriver_running(0); /* ok, we're done */
1993
return bpy_pydriver_obArrayFromList(); /* NULL if eval failed */
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)
2001
PyObject *retval, *bpy_ob = NULL;
2002
float result = 0.0f; /* default return */
2004
PyGILState_STATE gilstate;
2006
if (!driver || (G.f&G_DOSCRIPTLINKS)==0) return result;
2008
expr = driver->name; /* the py expression to be evaluated */
2009
if (!expr || expr[0]=='\0') return result;
2011
gilstate = PyGILState_Ensure();
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);
2022
bpy_ob = Object_CreatePyObject(driver->ob);
2029
setitem_retval = EXPP_dict_set_item_str(bpy_pydriver_Dict, "self", bpy_ob);
2031
if( !setup_armature_weakrefs()){
2032
fprintf( stderr, "Oops - weakref dict setup\n");
2033
PyGILState_Release(gilstate);
2037
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
2040
if (retval == NULL) {
2041
result = pydriver_error(driver);
2042
PyGILState_Release(gilstate);
2046
result = ( float )PyFloat_AsDouble( retval );
2049
if (result == -1 && PyErr_Occurred()) {
2050
result = pydriver_error(driver);
2051
PyGILState_Release(gilstate);
2055
/* remove 'self', since this dict is also used by py buttons */
2056
if (setitem_retval == 0) PyDict_DelItemString(bpy_pydriver_Dict, "self");
2058
/* all fine, make sure the "invalid expression" flag is cleared */
2059
driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
2061
PyGILState_Release(gilstate);
2066
/* Button Python Evaluation */
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.
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. */
2077
static int bpy_button_eval_error(char *expr) {
2079
if (bpy_pydriver_oblist)
2080
bpy_pydriver_freeList();
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;
2089
fprintf(stderr, "\nError in button evaluation:\nThis is the failed Python expression:\n'%s'\n\n", expr);
2096
int BPY_button_eval(char *expr, double *value)
2098
PyObject *retval, *floatval;
2099
PyGILState_STATE gilstate;
2102
if (!value || !expr || expr[0]=='\0') return -1;
2104
*value = 0.0; /* default value */
2106
gilstate = PyGILState_Ensure();
2108
if (!bpy_pydriver_Dict) {
2109
if (bpy_pydriver_create_dict() != 0) {
2111
"Button Python Eval error: couldn't create Python dictionary \n");
2112
PyGILState_Release(gilstate);
2118
if( !setup_armature_weakrefs()){
2119
fprintf(stderr, "Oops - weakref dict\n");
2120
PyGILState_Release(gilstate);
2124
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
2127
if (retval == NULL) {
2128
ret = bpy_button_eval_error(expr);
2129
PyGILState_Release(gilstate);
2133
floatval = PyNumber_Float(retval);
2137
if (floatval == NULL) {
2138
ret = bpy_button_eval_error(expr);
2139
PyGILState_Release(gilstate);
2142
*value = (float)PyFloat_AsDouble(floatval);
2143
Py_DECREF(floatval);
2146
PyGILState_Release(gilstate);
2148
return 0; /* successful exit */
2152
/*****************************************************************************/
2154
/*****************************************************************************/
2156
/*****************************************************************************/
2158
/* Notes: Not implemented yet */
2159
/*****************************************************************************/
2160
void BPY_clear_bad_scriptlinks( struct Text *byebye )
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);
2170
allqueue(REDRAWBUTSSCRIPT, 0);
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 )
2183
/* during stills rendering we disable FRAMECHANGED events */
2184
static char disable_frame_changed = 0;
2186
if ((event == SCRIPT_FRAMECHANGED) && disable_frame_changed)
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 );
2195
BPY_do_pyscript( &( G.scene->id ), event );
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();
2205
disable_frame_changed = 1;
2207
else if (event == SCRIPT_POSTRENDER) {
2208
_Py_CheckInterval = 100; /* Python default */
2209
disable_frame_changed = 0;
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
2221
*****************************************************************************/
2223
static ScriptLink *ID_getScriptlink( ID * id )
2225
switch ( MAKE_ID2( id->name[0], id->name[1] ) ) {
2227
return &( ( Object * ) id )->scriptlink;
2229
return &( ( Lamp * ) id )->scriptlink;
2231
return &( ( Camera * ) id )->scriptlink;
2233
return &( ( Material * ) id )->scriptlink;
2235
return &( ( World * ) id )->scriptlink;
2237
return &( ( Scene * ) id )->scriptlink;
2243
int BPY_has_onload_script( void )
2245
ScriptLink *slink = &G.scene->scriptlink;
2248
if( !slink || !slink->totscript )
2251
for( i = 0; i < slink->totscript; i++ ) {
2252
if( ( slink->flag[i] == SCRIPT_ONLOAD )
2253
&& ( slink->scripts[i] != NULL ) )
2260
void BPY_do_pyscript( ID * id, short event )
2262
ScriptLink *scriptlink;
2266
scriptlink = ID_getScriptlink( id );
2268
if( scriptlink && scriptlink->totscript ) {
2272
int index, during_slink = during_scriptlink( );
2273
PyGILState_STATE gilstate;
2275
/* invalid scriptlinks (new .blend was just loaded), return */
2276
if( during_slink < 0 )
2279
gilstate = PyGILState_Ensure();
2281
if( !setup_armature_weakrefs()){
2282
printf("Oops - weakref dict, this is a bug\n");
2283
PyGILState_Release(gilstate);
2287
value = GetPyObjectFromID( id );
2289
printf("Oops - could not get a valid python object for Blender.link, this is a bug\n");
2290
PyGILState_Release(gilstate);
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. */
2298
disable_where_scriptlink( (short)during_slink );
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
2306
if (event == SCRIPT_POSTRENDER) event = SCRIPT_RENDER;
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 );
2317
/* Failed execution of the script */
2318
BPY_Err_Handle( scriptlink->
2319
scripts[index]->name +
2321
//BPY_end_python ();
2322
//BPY_start_python ();
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 ) {
2336
disable_where_scriptlink( (short)(during_slink - 1) );
2338
/* cleanup bylink flag and clear link so PyObject
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( "" ) );
2345
PyGILState_Release(gilstate);
2350
/* SPACE HANDLERS */
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. */
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 */
2366
int BPY_has_spacehandler(Text *text, ScrArea *sa)
2371
if (!sa || !text) return 0;
2373
slink = &sa->scriptlink;
2375
for (index = 0; index < slink->totscript; index++) {
2376
if (slink->scripts[index] && (slink->scripts[index] == (ID *)text))
2383
int BPY_is_spacehandler(Text *text, char spacetype)
2385
TextLine *tline = text->lines.first;
2386
unsigned short type = 0;
2388
if (tline && (tline->len > 10)) {
2389
char *line = tline->line;
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 '#' */
2397
/* only done for 3D View right now, trivial to add for others: */
2398
switch (spacetype) {
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;
2408
return type; /* 0 if not a space handler */
2411
int BPY_del_spacehandler(Text *text, ScrArea *sa)
2416
if (!sa || !text) return -1;
2418
slink = &sa->scriptlink;
2419
if (slink->totscript < 1) return -1;
2421
for (i = 0; i < slink->totscript; i++) {
2422
if (text == (Text *)slink->scripts[i]) {
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];
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);
2442
int BPY_add_spacehandler(Text *text, ScrArea *sa, char spacetype)
2444
unsigned short handlertype;
2446
if (!sa || !text) return -1;
2448
handlertype = (unsigned short)BPY_is_spacehandler(text, spacetype);
2451
ScriptLink *slink = &sa->scriptlink;
2453
unsigned short space_event = SPACEHANDLER_VIEW3D_EVENT;
2457
stmp= slink->scripts;
2458
slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1),
2459
"spacehandlerscripts");
2462
slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1),
2463
"spacehandlerflags");
2465
if (slink->totscript) {
2466
memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript));
2469
memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript));
2473
switch (spacetype) {
2475
if (handlertype == 1) space_event = SPACEHANDLER_VIEW3D_EVENT;
2476
else space_event = SPACEHANDLER_VIEW3D_DRAW;
2482
slink->scripts[slink->totscript] = (ID *)text;
2483
slink->flag[slink->totscript]= space_event;
2486
slink->actscript = slink->totscript;
2492
int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
2493
short eventValue, unsigned short space_event )
2495
ScriptLink *scriptlink;
2497
PyGILState_STATE gilstate;
2499
if (!sa || !(G.f & G_DOSCRIPTLINKS)) return 0;
2501
scriptlink = &sa->scriptlink;
2503
if (scriptlink->totscript > 0) {
2506
int index, during_slink = during_scriptlink();
2508
/* invalid scriptlinks (new .blend was just loaded), return */
2509
if (during_slink < 0) return 0;
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 */
2518
disable_where_scriptlink( (short)during_slink );
2521
gilstate = PyGILState_Ensure();
2523
if( !setup_armature_weakrefs()){
2524
printf("Oops - weakref dict, this is a bug\n");
2525
PyGILState_Release(gilstate);
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++ ) {
2539
/* for DRAW handlers: */
2541
glPushAttrib(GL_ALL_ATTRIB_BITS);
2542
glMatrixMode(GL_PROJECTION);
2544
glMatrixMode(GL_MODELVIEW);
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 );
2554
if (!ret) { /* Failed execution of the script */
2555
BPY_Err_Handle( scriptlink->scripts[index]->name+2 );
2559
/* an EVENT type (event != 0) script can either accept an event or
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 */
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 ) {
2573
if (event == 0) glPopAttrib();
2578
/* for DRAW handlers: */
2580
glMatrixMode(GL_PROJECTION);
2582
glMatrixMode(GL_MODELVIEW);
2585
disable_where_scriptlink( (short)(during_slink - 1) );
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(""));
2594
PyGILState_Release(gilstate);
2598
* space_event is of type EVENT:
2599
* 0 - event was returned,
2600
* 1 - event was processed;
2601
* space_event is of type DRAW:
2607
/*****************************************************************************
2610
*****************************************************************************/
2611
void BPY_free_scriptlink( struct ScriptLink *slink )
2613
if( slink->totscript ) {
2615
MEM_freeN( slink->flag );
2618
if( slink->scripts ) {
2619
MEM_freeN( slink->scripts );
2620
slink->scripts= NULL;
2627
static int CheckAllSpaceHandlers(Text *text)
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++;
2644
static int CheckAllScriptsFromList( ListBase * list, Text * text )
2647
ScriptLink *scriptlink;
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;
2669
/* When a Text is deleted, we need to unlink it from eventual scriptlinks */
2670
int BPY_check_all_scriptlinks( Text * text )
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);
2684
/*****************************************************************************
2687
*****************************************************************************/
2688
void BPY_copy_scriptlink( struct ScriptLink *scriptlink )
2692
if( scriptlink->totscript ) {
2694
tmp = scriptlink->scripts;
2695
scriptlink->scripts =
2696
MEM_mallocN( sizeof( ID * ) * scriptlink->totscript,
2698
memcpy( scriptlink->scripts, tmp,
2699
sizeof( ID * ) * scriptlink->totscript );
2701
tmp = scriptlink->flag;
2703
MEM_mallocN( sizeof( short ) * scriptlink->totscript,
2705
memcpy( scriptlink->flag, tmp,
2706
sizeof( short ) * scriptlink->totscript );
2712
/****************************************************************************
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 );
2722
/*****************************************************************************
2724
*****************************************************************************/
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 )
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 */
2738
if( !text->compiled ) { /* if it wasn't already compiled, do it now */
2739
buf = txt_to_buf( text );
2742
Py_CompileString( buf, text->id.name+2, Py_file_input );
2746
if( PyErr_Occurred( ) ) {
2747
BPY_free_compiled_text( text );
2753
return PyEval_EvalCode( text->compiled, globaldict, globaldict );
2756
/*****************************************************************************
2757
* Description: This function creates a new Python dictionary object.
2758
*****************************************************************************/
2759
static PyObject *CreateGlobalDictionary( void )
2761
PyObject *dict = PyDict_New( );
2763
PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins( ) );
2764
EXPP_dict_set_item_str( dict, "__name__",
2765
PyString_FromString( "__main__" ) );
2770
/*****************************************************************************
2771
* Description: This function deletes a given Python dictionary object.
2772
*****************************************************************************/
2773
static void ReleaseGlobalDictionary( PyObject * dict )
2775
PyDict_Clear( dict );
2776
Py_DECREF( dict ); /* Release dictionary. */
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 )
2792
while( id != NULL ) {
2793
BPY_do_pyscript( id, event );
2800
static PyObject *importText( char *name )
2803
char txtname[22]; /* 21+NULL */
2805
int namelen = strlen( name );
2807
if (namelen>21-3) return NULL; /* we know this cant be importable, the name is too long for blender! */
2809
memcpy( txtname, name, namelen );
2810
memcpy( &txtname[namelen], ".py", 4 );
2812
for(text = G.main->text.first; text; text = text->id.next) {
2813
if( !strcmp( txtname, text->id.name+2 ) )
2820
if( !text->compiled ) {
2821
buf = txt_to_buf( text );
2822
text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
2825
if( PyErr_Occurred( ) ) {
2827
BPY_free_compiled_text( text );
2832
return PyImport_ExecCodeModule( name, text->compiled );
2835
static PyMethodDef bimport[] = {
2836
{"blimport", blender_import, METH_VARARGS, "our own import"}
2839
static PyObject *blender_import( PyObject * self, PyObject * args )
2841
PyObject *exception, *err, *tb;
2843
PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
2845
//PyObject_Print(args, stderr, 0);
2846
#if (PY_VERSION_HEX >= 0x02060000)
2847
int dummy_val; /* what does this do?*/
2849
if( !PyArg_ParseTuple( args, "s|OOOi:bimport",
2850
&name, &globals, &locals, &fromlist, &dummy_val) )
2853
if( !PyArg_ParseTuple( args, "s|OOO:bimport",
2854
&name, &globals, &locals, &fromlist ) )
2857
m = PyImport_ImportModuleEx( name, globals, locals, fromlist );
2862
PyErr_Fetch( &exception, &err, &tb ); /*restore for probable later use */
2864
m = importText( name );
2865
if( m ) { /* found module, ignore above exception */
2867
Py_XDECREF( exception );
2870
printf( "imported from text buffer...\n" );
2872
PyErr_Restore( exception, err, tb );
2877
static void init_ourImport( void )
2880
PyObject *import = PyCFunction_New( bimport, NULL );
2882
m = PyImport_AddModule( "__builtin__" );
2883
d = PyModule_GetDict( m );
2885
EXPP_dict_set_item_str( d, "__import__", import );
2889
* find in-memory module and recompile
2892
static PyObject *reimportText( PyObject *module )
2899
/* get name, filename from the module itself */
2901
txtname = PyModule_GetFilename( module );
2902
name = PyModule_GetName( module );
2903
if( !txtname || !name)
2906
/* look up the text object */
2907
text = ( Text * ) & ( G.main->text.first );
2909
if( !strcmp( txtname, text->id.name+2 ) )
2911
text = text->id.next;
2914
/* uh-oh.... didn't find it */
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 );
2924
/* compile the buffer */
2925
buf = txt_to_buf( text );
2926
text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
2929
/* if compile failed.... return this error */
2930
if( PyErr_Occurred( ) ) {
2932
BPY_free_compiled_text( text );
2936
/* make into a module */
2937
return PyImport_ExecCodeModule( name, text->compiled );
2941
* our reload() module, to handle reloading in-memory scripts
2944
static PyObject *blender_reload( PyObject * self, PyObject * args )
2946
PyObject *exception, *err, *tb;
2947
PyObject *module = NULL;
2948
PyObject *newmodule = NULL;
2950
/* check for a module arg */
2951
if( !PyArg_ParseTuple( args, "O:breload", &module ) )
2954
/* try reimporting from file */
2955
newmodule = PyImport_ReloadModule( module );
2959
/* no file, try importing from memory */
2960
PyErr_Fetch( &exception, &err, &tb ); /*restore for probable later use */
2962
newmodule = reimportText( module );
2963
if( newmodule ) { /* found module, ignore above exception */
2965
Py_XDECREF( exception );
2969
PyErr_Restore( exception, err, tb );
2974
static PyMethodDef breload[] = {
2975
{"blreload", blender_reload, METH_VARARGS, "our own reload"}
2978
static void init_ourReload( void )
2981
PyObject *reload = PyCFunction_New( breload, NULL );
2983
m = PyImport_AddModule( "__builtin__" );
2984
d = PyModule_GetDict( m );
2985
EXPP_dict_set_item_str( d, "reload", reload );
2989
void BPY_scripts_clear_pyobjects( void )
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)
3001
void error_pyscript( void )
3003
error("Python script error: check console");