25
25
* This is a new part of Blender.
27
* Contributor(s): Michel Selten, Willian P. Germano, Joseph Gilbert
27
* Contributor(s): Michel Selten, Willian P. Germano, Joseph Gilbert,
29
30
* ***** END GPL/BL DUAL LICENSE BLOCK *****
32
//#include "BKE_utildefines.h"
33
#include "BIF_usiblender.h"
37
/*****************************************************************************/
38
/* Global variables */
40
/* for open, close in Blender_Load */
48
#include <BDR_editobject.h> /* exit_editmode() */
49
#include <BIF_usiblender.h>
50
#include <BLI_blenlib.h>
51
#include <BLO_writefile.h>
52
#include <BKE_exotic.h>
53
#include <BKE_global.h>
54
#include <BKE_packedFile.h>
55
#include <BKE_object.h>
57
#include <BPI_script.h>
58
#include <BSE_headerbuttons.h>
60
#include <DNA_object_types.h>
61
#include <DNA_scene_types.h>
62
#include <DNA_screen_types.h> /* for SPACE_VIEW3D */
63
#include <DNA_space_types.h> /* for SPACE_VIEW3D */
64
#include <DNA_scriptlink_types.h>
65
#include <DNA_userdef_types.h>
69
#include "EXPP_interface.h" /* for bpy_gethome() */
70
#include "gen_utils.h"
73
#include "../BPY_extern.h" /* BPY_txt_do_python_Text */
74
#include "../BPY_menus.h" /* to update menus */
76
extern PyObject *bpy_registryDict; /* defined in ../BPY_interface.c */
78
/**********************************************************/
79
/* Python API function prototypes for the Blender module. */
80
/**********************************************************/
81
static PyObject *Blender_Set( PyObject * self, PyObject * args );
82
static PyObject *Blender_Get( PyObject * self, PyObject * args );
83
static PyObject *Blender_Redraw( PyObject * self, PyObject * args );
84
static PyObject *Blender_Quit( PyObject * self );
85
static PyObject *Blender_Load( PyObject * self, PyObject * args );
86
static PyObject *Blender_Save( PyObject * self, PyObject * args );
87
static PyObject *Blender_Run( PyObject * self, PyObject * args );
88
static PyObject *Blender_ShowHelp( PyObject * self, PyObject * args );
89
static PyObject *Blender_UpdateMenus( PyObject * self);
91
extern PyObject *Text3d_Init( void ); /* missing in some include */
93
/*****************************************************************************/
94
/* The following string definitions are used for documentation strings. */
95
/* In Python these will be written to the console when doing a */
97
/*****************************************************************************/
98
static char Blender_Set_doc[] =
99
"(request, data) - Update settings in Blender\n\
101
(request) A string identifying the setting to change\n\
102
'curframe' - Sets the current frame using the number in data";
104
static char Blender_Get_doc[] = "(request) - Retrieve settings from Blender\n\
106
(request) A string indentifying the data to be returned\n\
107
'curframe' - Returns the current animation frame\n\
108
'curtime' - Returns the current animation time\n\
109
'staframe' - Returns the start frame of the animation\n\
110
'endframe' - Returns the end frame of the animation\n\
111
'filename' - Returns the name of the last file read or written\n\
112
'homedir' - Returns Blender's home dir\n\
113
'datadir' - Returns the dir where scripts can save their data, if available\n\
114
'scriptsdir' - Returns the main dir where scripts are kept, if available\n\
115
'uscriptsdir' - Returns the user defined dir for scripts, if available\n\
116
'version' - Returns the Blender version number";
118
static char Blender_Redraw_doc[] = "() - Redraw all 3D windows";
120
static char Blender_Quit_doc[] =
121
"() - Quit Blender. The current data is saved as 'quit.blend' before leaving.";
123
static char Blender_Load_doc[] = "(filename) - Load the given file.\n\
124
Supported formats:\n\
125
Blender, DXF, Inventor 1.0 ASCII, VRML 1.0 asc, STL, Videoscape, radiogour.\n\
128
1 - () - an empty argument loads the default .B.blend file;\n\
129
2 - if the substring '.B.blend' occurs inside 'filename', the default\n\
130
.B.blend file is loaded;\n\
131
3 - If a Blender file is loaded the script ends immediately.\n\
132
4 - The current data is always preserved as an autosave file, for safety;\n\
133
5 - This function only works if the script where it's executed is the\n\
134
only one running at the moment.";
136
static char Blender_Save_doc[] =
137
"(filename) - Save data to a file based on the filename's extension.\n\
138
Supported are: Blender's .blend and the builtin exporters:\n\
139
VRML 1.0 (.wrl), Videoscape (.obj), DXF (.dxf) and STL (.stl)\n\
140
(filename) - A filename with one of the supported extensions.\n\
141
Note 1: 'filename' should not contain the substring \".B.blend\" in it.\n\
142
Note 2: only .blend raises an error if file wasn't saved.\n\
143
\tYou can use Blender.sys.exists(filename) to make sure the file was saved\n\
144
\twhen writing to one of the other formats.";
146
static char Blender_Run_doc[] =
147
"(script) - Run the given Python script.\n\
148
(script) - the path to a file or the name of an available Blender Text.";
150
static char Blender_ShowHelp_doc[] =
151
"(script) - Show help for the given Python script.\n\
152
This will try to open the 'Scripts Help Browser' script, so to have\n\
153
any help displayed the passed 'script' must be properly documented\n\
154
with the expected strings (check API ref docs or any bundled script\n\
156
(script) - the filename of a script in the default or user defined\n\
157
scripts dir (no need to supply the full path name).";
159
static char Blender_UpdateMenus_doc[] =
160
"() - Update the menus where scripts are registered. Only needed for\n\
161
scripts that save other new scripts in the default or user defined folders.";
163
/*****************************************************************************/
164
/* Python method structure definition. */
165
/*****************************************************************************/
166
static struct PyMethodDef Blender_methods[] = {
167
{"Set", Blender_Set, METH_VARARGS, Blender_Set_doc},
168
{"Get", Blender_Get, METH_VARARGS, Blender_Get_doc},
169
{"Redraw", Blender_Redraw, METH_VARARGS, Blender_Redraw_doc},
170
{"Quit", ( PyCFunction ) Blender_Quit, METH_NOARGS, Blender_Quit_doc},
171
{"Load", Blender_Load, METH_VARARGS, Blender_Load_doc},
172
{"Save", Blender_Save, METH_VARARGS, Blender_Save_doc},
173
{"Run", Blender_Run, METH_VARARGS, Blender_Run_doc},
174
{"ShowHelp", Blender_ShowHelp, METH_VARARGS, Blender_ShowHelp_doc},
175
{"UpdateMenus", ( PyCFunction ) Blender_UpdateMenus, METH_NOARGS,
176
Blender_UpdateMenus_doc},
177
{NULL, NULL, 0, NULL}
180
/*****************************************************************************/
181
/* Global variables */
39
182
/*****************************************************************************/
40
183
PyObject *g_blenderdict;
42
185
/*****************************************************************************/
43
/* Function: Blender_Set */
44
/* Python equivalent: Blender.Set */
186
/* Function: Blender_Set */
187
/* Python equivalent: Blender.Set */
45
188
/*****************************************************************************/
46
PyObject *Blender_Set (PyObject *self, PyObject *args)
189
static PyObject *Blender_Set( PyObject * self, PyObject * args )
52
if (!PyArg_ParseTuple(args, "sO", &name, &arg))
195
if( !PyArg_ParseTuple( args, "sO", &name, &arg ) ) {
54
196
/* TODO: Do we need to generate a nice error message here? */
58
if (StringEqual (name, "curframe"))
60
if (!PyArg_Parse(arg, "i", &framenum))
62
/* TODO: Do we need to generate a nice error message here? */
200
if( StringEqual( name, "curframe" ) ) {
201
if( !PyArg_Parse( arg, "i", &framenum ) ) {
202
/* TODO: Do we need to generate a nice error message here? */
66
206
G.scene->r.cfra = framenum;
68
update_for_newframe();
72
return (PythonReturnErrorObject (PyExc_AttributeError,
73
"bad request identifier"));
75
return ( PythonIncRef (Py_None) );
208
update_for_newframe( );
210
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
211
"bad request identifier" ) );
213
return ( EXPP_incr_ret( Py_None ) );
78
216
/*****************************************************************************/
79
/* Function: Blender_Get */
80
/* Python equivalent: Blender.Get */
217
/* Function: Blender_Get */
218
/* Python equivalent: Blender.Get */
81
219
/*****************************************************************************/
82
PyObject *Blender_Get (PyObject *self, PyObject *args)
220
static PyObject *Blender_Get( PyObject * self, PyObject * args )
88
if (!PyArg_ParseTuple (args, "O", &object))
90
/* TODO: Do we need to generate a nice error message here? */
94
if (PyString_Check (object))
96
str = PyString_AsString (object);
98
if (StringEqual (str, "curframe"))
100
return ( PyInt_FromLong (G.scene->r.cfra) );
102
if (StringEqual (str, "curtime"))
104
return ( PyFloat_FromDouble (frame_to_float (G.scene->r.cfra) ) );
106
if (StringEqual (str, "staframe"))
108
return ( PyInt_FromLong (G.scene->r.sfra) );
110
if (StringEqual (str, "endframe"))
112
return ( PyInt_FromLong (G.scene->r.efra) );
114
if (StringEqual (str, "filename"))
116
return ( PyString_FromString (G.sce) );
118
/* According to the old file (opy_blender.c), the following if
119
statement is a quick hack and needs some clean up. */
120
if (StringEqual (str, "vrmloptions"))
122
dict = PyDict_New ();
124
PyDict_SetItemString (dict, "twoside",
125
PyInt_FromLong (U.vrmlflag & USER_VRML_TWOSIDED));
127
PyDict_SetItemString (dict, "layers",
128
PyInt_FromLong (U.vrmlflag & USER_VRML_LAYERS));
130
PyDict_SetItemString (dict, "autoscale",
131
PyInt_FromLong (U.vrmlflag & USER_VRML_AUTOSCALE));
134
} /* End 'quick hack' part. */
135
if (StringEqual (str, "version"))
137
return ( PyInt_FromLong (G.version) );
139
/* TODO: Do we want to display a usefull message here that the
140
requested data is unknown?
143
return (PythonReturnErrorObject (..., "message") );
149
return (PythonReturnErrorObject (PyExc_AttributeError,
150
"expected string argument"));
153
return (PythonReturnErrorObject (PyExc_AttributeError,
154
"bad request identifier"));
222
PyObject *ret = NULL, *dict = NULL;
225
if( !PyArg_ParseTuple( args, "s", &str ) )
226
return EXPP_ReturnPyObjError (PyExc_TypeError,
227
"expected string argument");
229
if( StringEqual( str, "curframe" ) )
230
ret = PyInt_FromLong( G.scene->r.cfra );
231
else if( StringEqual( str, "curtime" ) )
232
ret = PyFloat_FromDouble( frame_to_float( G.scene->r.cfra ) );
233
else if( StringEqual( str, "staframe" ) )
234
ret = PyInt_FromLong( G.scene->r.sfra );
235
else if( StringEqual( str, "endframe" ) )
236
ret = PyInt_FromLong( G.scene->r.efra );
237
else if( StringEqual( str, "filename" ) )
238
ret = PyString_FromString( G.sce );
239
else if( StringEqual( str, "homedir" ) ) {
240
char *hdir = bpy_gethome(0);
241
if( hdir && BLI_exists( hdir ))
242
ret = PyString_FromString( hdir );
244
ret = EXPP_incr_ret( Py_None );
246
else if( StringEqual( str, "datadir" ) ) {
247
char datadir[FILE_MAXDIR];
248
char *sdir = bpy_gethome(1);
251
BLI_make_file_string( "/", datadir, sdir, "bpydata" );
252
if( BLI_exists( datadir ) )
253
ret = PyString_FromString( datadir );
255
if (!ret) ret = EXPP_incr_ret( Py_None );
257
else if(StringEqual(str, "udatadir")) {
258
if (U.pythondir[0] != '\0') {
259
char upydir[FILE_MAXDIR];
261
BLI_strncpy(upydir, U.pythondir, FILE_MAXDIR);
262
BLI_convertstringcode(upydir, G.sce, 0);
264
if (BLI_exists(upydir)) {
265
char udatadir[FILE_MAXDIR];
267
BLI_make_file_string("/", udatadir, upydir, "bpydata");
269
if (BLI_exists(udatadir))
270
ret = PyString_FromString(udatadir);
273
if (!ret) ret = EXPP_incr_ret(Py_None);
275
else if( StringEqual( str, "scriptsdir" ) ) {
276
char *sdir = bpy_gethome(1);
279
ret = PyString_FromString(sdir);
281
ret = EXPP_incr_ret( Py_None );
283
else if( StringEqual( str, "uscriptsdir" ) ) {
284
if (U.pythondir[0] != '\0') {
285
char upydir[FILE_MAXDIR];
287
BLI_strncpy(upydir, U.pythondir, FILE_MAXDIR);
288
BLI_convertstringcode(upydir, G.sce, 0);
290
if( BLI_exists( upydir ) )
291
ret = PyString_FromString( upydir );
293
if (!ret) ret = EXPP_incr_ret(Py_None);
296
else if( StringEqual( str, "yfexportdir" ) ) {
297
if (U.yfexportdir[0] != '\0') {
298
char yfexportdir[FILE_MAXDIR];
300
BLI_strncpy(yfexportdir, U.yfexportdir, FILE_MAXDIR);
301
BLI_convertstringcode(yfexportdir, G.sce, 0);
303
if( BLI_exists( yfexportdir ) )
304
ret = PyString_FromString( yfexportdir );
306
if (!ret) ret = EXPP_incr_ret(Py_None);
309
else if( StringEqual( str, "fontsdir" ) ) {
310
if (U.fontdir[0] != '\0') {
311
char fontdir[FILE_MAXDIR];
313
BLI_strncpy(fontdir, U.fontdir, FILE_MAXDIR);
314
BLI_convertstringcode(fontdir, G.sce, 0);
316
if( BLI_exists( fontdir ) )
317
ret = PyString_FromString( fontdir );
319
if (!ret) ret = EXPP_incr_ret(Py_None);
322
else if( StringEqual( str, "texturesdir" ) ) {
323
if (U.textudir[0] != '\0') {
324
char textudir[FILE_MAXDIR];
326
BLI_strncpy(textudir, U.textudir, FILE_MAXDIR);
327
BLI_convertstringcode(textudir, G.sce, 0);
329
if( BLI_exists( textudir ) )
330
ret = PyString_FromString( textudir );
332
if (!ret) ret = EXPP_incr_ret(Py_None);
335
else if( StringEqual( str, "texpluginsdir" ) ) {
336
if (U.plugtexdir[0] != '\0') {
337
char plugtexdir[FILE_MAXDIR];
339
BLI_strncpy(plugtexdir, U.plugtexdir, FILE_MAXDIR);
340
BLI_convertstringcode(plugtexdir, G.sce, 0);
342
if( BLI_exists( plugtexdir ) )
343
ret = PyString_FromString( plugtexdir );
345
if (!ret) ret = EXPP_incr_ret(Py_None);
348
else if( StringEqual( str, "seqpluginsdir" ) ) {
349
if (U.plugseqdir[0] != '\0') {
350
char plugseqdir[FILE_MAXDIR];
352
BLI_strncpy(plugseqdir, U.plugseqdir, FILE_MAXDIR);
353
BLI_convertstringcode(plugseqdir, G.sce, 0);
355
if( BLI_exists( plugseqdir ) )
356
ret = PyString_FromString( plugseqdir );
358
if (!ret) ret = EXPP_incr_ret(Py_None);
361
else if( StringEqual( str, "renderdir" ) ) {
362
if (U.renderdir[0] != '\0') {
363
char renderdir[FILE_MAXDIR];
365
BLI_strncpy(renderdir, U.renderdir, FILE_MAXDIR);
366
BLI_convertstringcode(renderdir, G.sce, 0);
368
if( BLI_exists( renderdir ) )
369
ret = PyString_FromString( renderdir );
371
if (!ret) ret = EXPP_incr_ret(Py_None);
374
else if( StringEqual( str, "soundsdir" ) ) {
375
if (U.sounddir[0] != '\0') {
376
char sounddir[FILE_MAXDIR];
378
BLI_strncpy(sounddir, U.sounddir, FILE_MAXDIR);
379
BLI_convertstringcode(sounddir, G.sce, 0);
381
if( BLI_exists( sounddir ) )
382
ret = PyString_FromString( sounddir );
384
if (!ret) ret = EXPP_incr_ret(Py_None);
387
else if( StringEqual( str, "tempdir" ) ) {
388
if (U.tempdir[0] != '\0') {
389
char tempdir[FILE_MAXDIR];
391
BLI_strncpy(tempdir, U.tempdir, FILE_MAXDIR);
392
BLI_convertstringcode(tempdir, G.sce, 0);
394
if( BLI_exists( tempdir ) )
395
ret = PyString_FromString( tempdir );
397
if (!ret) ret = EXPP_incr_ret(Py_None);
399
/* According to the old file (opy_blender.c), the following if
400
statement is a quick hack and needs some clean up. */
401
else if( StringEqual( str, "vrmloptions" ) ) {
404
PyDict_SetItemString( dict, "twoside",
405
PyInt_FromLong( U.vrmlflag & USER_VRML_TWOSIDED ) );
407
PyDict_SetItemString( dict, "layers",
408
PyInt_FromLong( U.vrmlflag & USER_VRML_LAYERS ) );
410
PyDict_SetItemString( dict, "autoscale",
411
PyInt_FromLong( U.vrmlflag & USER_VRML_AUTOSCALE ) );
413
} /* End 'quick hack' part. */
414
else if(StringEqual( str, "version" ))
415
ret = PyInt_FromLong( G.version );
417
return EXPP_ReturnPyObjError( PyExc_AttributeError, "unknown attribute" );
421
return EXPP_ReturnPyObjError (PyExc_MemoryError,
422
"could not create pystring!");
157
425
/*****************************************************************************/
158
/* Function: Blender_Redraw */
159
/* Python equivalent: Blender.Redraw */
426
/* Function: Blender_Redraw */
427
/* Python equivalent: Blender.Redraw */
160
428
/*****************************************************************************/
161
PyObject *Blender_Redraw(PyObject *self, PyObject *args)
429
static PyObject *Blender_Redraw( PyObject * self, PyObject * args )
163
431
int wintype = SPACE_VIEW3D;
165
if (!PyArg_ParseTuple (args, "|i", &wintype))
167
return EXPP_ReturnPyObjError (PyExc_TypeError,
168
"expected int argument (or nothing)");
171
return M_Window_Redraw(self, Py_BuildValue("(i)", wintype));
174
/*****************************************************************************/
175
/* Function: Blender_ReleaseGlobalDict */
176
/* Python equivalent: Blender.ReleaseGlobalDict */
177
/* Description: Deprecated function. */
178
/*****************************************************************************/
179
PyObject *Blender_ReleaseGlobalDict(PyObject *self, PyObject *args)
185
/*****************************************************************************/
186
/* Function: Blender_Quit */
187
/* Python equivalent: Blender.Quit */
188
/*****************************************************************************/
189
PyObject *Blender_Quit(PyObject *self)
197
/*****************************************************************************/
198
/* Function: initBlender */
199
/*****************************************************************************/
200
void M_Blender_Init (void)
433
if( !PyArg_ParseTuple( args, "|i", &wintype ) ) {
434
return EXPP_ReturnPyObjError( PyExc_TypeError,
435
"expected int argument (or nothing)" );
438
return M_Window_Redraw( self, Py_BuildValue( "(i)", wintype ) );
441
/*****************************************************************************/
442
/* Function: Blender_Quit */
443
/* Python equivalent: Blender.Quit */
444
/*****************************************************************************/
445
static PyObject *Blender_Quit( PyObject * self )
447
BIF_write_autosave( ); /* save the current data first */
449
exit_usiblender( ); /* renames last autosave to quit.blend */
451
Py_INCREF( Py_None );
457
* loads Blender's .blend, DXF, radiogour(?), STL, Videoscape,
458
* Inventor 1.0 ASCII, VRML 1.0 asc.
460
static PyObject *Blender_Load( PyObject * self, PyObject * args )
463
int keep_oldfname = 0;
464
Script *script = NULL;
465
char str[32], name[FILE_MAXDIR];
466
int file, is_blend_file = 0;
468
if( !PyArg_ParseTuple( args, "|si", &fname, &keep_oldfname ) )
469
return EXPP_ReturnPyObjError( PyExc_TypeError,
470
"expected filename and optional int or nothing as arguments" );
473
if( strlen( fname ) > FILE_MAXDIR ) /* G.main->name's max length */
474
return EXPP_ReturnPyObjError( PyExc_AttributeError,
475
"filename too long!" );
476
else if( !BLI_exists( fname ) )
477
return EXPP_ReturnPyObjError( PyExc_AttributeError,
478
"requested file doesn't exist!" );
481
BLI_strncpy( name, G.sce, FILE_MAXDIR );
484
/* We won't let a new .blend file be loaded if there are still other
485
* scripts running, since loading a new file will close and remove them. */
487
if( G.main->script.first != G.main->script.last )
488
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
489
"there are other scripts running at the Scripts win, close them first!" );
492
file = open( fname, O_BINARY | O_RDONLY );
495
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
496
"cannot open file!" );
498
read( file, str, 31 );
501
if( strncmp( str, "BLEN", 4 ) == 0 )
505
is_blend_file = 1; /* no arg given means default: .B.blend */
507
if( is_blend_file ) {
508
int during_slink = during_scriptlink( );
510
/* when loading a .blend file from a scriptlink, the scriptlink pointer
511
* in BPY_do_pyscript becomes invalid during a loop. Inform it here.
512
* Also do not allow a nested scriptlink (called from inside another)
513
* to load .blend files, to avoid nasty problems. */
514
if( during_slink >= 1 ) {
515
if( during_slink == 1 )
516
disable_where_scriptlink( -1 );
518
return EXPP_ReturnPyObjError
519
( PyExc_EnvironmentError,
520
"Blender.Load: cannot load .blend files from a nested scriptlink." );
524
/* trick: mark the script so that its script struct won't be freed after
525
* the script is executed (to avoid a double free warning on exit): */
526
script = G.main->script.first;
528
script->flags |= SCRIPT_GUI;
530
BIF_write_autosave( ); /* for safety let's preserve the current data */
536
/* for safety, any filename with .B.blend is considered the default one.
537
* It doesn't seem necessary to compare file attributes (like st_ino and
538
* st_dev, according to the glibc info pages) to find out if the given
539
* filename, that may have been given with a twisted misgiving path, is the
540
* default one for sure. Taking any .B.blend file as the default is good
541
* enough here. Note: the default file requires extra clean-up done by
542
* BIF_read_homefile: freeing the user theme data. */
543
if( !fname || ( strstr( fname, ".B.blend" ) && is_blend_file ) )
544
BIF_read_homefile( );
546
BIF_read_file( fname );
548
if( fname && keep_oldfname ) {
549
/*BLI_strncpy(G.main->name, name, FILE_MAXDIR); */
550
BLI_strncpy( G.sce, name, FILE_MAXDIR );
553
Py_INCREF( Py_None );
557
static PyObject *Blender_Save( PyObject * self, PyObject * args )
560
int overwrite = 0, len = 0;
564
if( !PyArg_ParseTuple( args, "s|i", &fname, &overwrite ) )
565
return EXPP_ReturnPyObjError( PyExc_TypeError,
566
"expected filename and optional int (overwrite flag) as arguments" );
568
for( li = G.main->library.first; li; li = li->id.next ) {
569
if( BLI_streq( li->name, fname ) ) {
570
return EXPP_ReturnPyObjError( PyExc_AttributeError,
571
"cannot overwrite used library" );
575
/* for safety, any filename with .B.blend is considered the default one
576
* and not accepted here. */
577
if( strstr( fname, ".B.blend" ) )
578
return EXPP_ReturnPyObjError( PyExc_AttributeError,
579
"filename can't contain the substring \".B.blend\" in it." );
581
len = strlen( fname );
583
if( len > FILE_MAXFILE )
584
return EXPP_ReturnPyObjError( PyExc_AttributeError,
585
"filename is too long!" );
586
else if( BLI_exists( fname ) && !overwrite )
587
return EXPP_ReturnPyObjError( PyExc_AttributeError,
588
"file already exists and overwrite flag was not given." );
590
disable_where_script( 1 ); /* to avoid error popups in the write_* functions */
592
if( BLI_testextensie( fname, ".blend" ) ) {
593
if( G.fileflags & G_AUTOPACK )
595
if( !BLO_write_file( fname, G.fileflags, &error ) ) {
596
disable_where_script( 0 );
597
return EXPP_ReturnPyObjError( PyExc_SystemError,
600
} else if( BLI_testextensie( fname, ".dxf" ) )
602
else if( BLI_testextensie( fname, ".stl" ) )
604
else if( BLI_testextensie( fname, ".wrl" ) )
606
else if( BLI_testextensie( fname, ".obj" ) )
607
write_videoscape( fname );
609
disable_where_script( 0 );
610
return EXPP_ReturnPyObjError( PyExc_AttributeError,
611
"unknown file extension." );
614
disable_where_script( 0 );
616
Py_INCREF( Py_None );
620
static PyObject *Blender_ShowHelp(PyObject *self, PyObject *args)
622
PyObject *script = NULL;
623
char hspath[FILE_MAXDIR + FILE_MAXFILE]; /* path to help_browser.py */
624
char *sdir = bpy_gethome(1);
625
PyObject *rkeyd = NULL, *arglist = NULL;
627
if (!PyArg_ParseTuple(args, "O!", &PyString_Type, &script))
628
return EXPP_ReturnPyObjError(PyExc_TypeError,
629
"expected a script filename as argument");
631
/* first we try to find the help_browser script */
633
if (sdir) BLI_make_file_string("/", hspath, sdir, "help_browser.py");
635
if (!sdir || (!BLI_exists(hspath) && (U.pythondir[0] != '\0'))) {
636
char upydir[FILE_MAXDIR];
638
BLI_strncpy(upydir, U.pythondir, FILE_MAXDIR);
639
BLI_convertstringcode(upydir, G.sce, 0);
640
BLI_make_file_string("/", hspath, upydir, "help_browser.py");
642
if (!BLI_exists(hspath))
643
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
644
"can't find script help_browser.py");
647
/* now we store the passed script in the registry dict and call the
648
* help_browser to show help info for it */
649
rkeyd = PyDict_New();
651
return EXPP_ReturnPyObjError(PyExc_MemoryError,
652
"can't create py dictionary!");
654
PyDict_SetItemString(rkeyd, "script", script);
655
PyDict_SetItemString(bpy_registryDict, "__help_browser", rkeyd);
657
arglist = Py_BuildValue("(s)", hspath);
658
Blender_Run(self, arglist);
661
return EXPP_incr_ret(Py_None);
664
static PyObject *Blender_Run(PyObject *self, PyObject *args)
668
int is_blender_text = 0;
669
Script *script = NULL;
671
if (!PyArg_ParseTuple(args, "s", &fname))
672
return EXPP_ReturnPyObjError(PyExc_TypeError,
673
"expected a filename or a Blender Text name as argument");
675
if (!BLI_exists(fname)) { /* if there's no such filename ... */
676
text = G.main->text.first; /* try an already existing Blender Text */
679
if (!strcmp(fname, text->id.name + 2)) break;
680
text = text->id.next;
684
return EXPP_ReturnPyObjError(PyExc_AttributeError,
685
"no such file or Blender text");
687
else is_blender_text = 1; /* fn is already a Blender Text */
691
text = add_text(fname);
694
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
695
"couldn't create Blender Text from given file");
699
/* (this is messy, check Draw.c's Method_Register and Window.c's file
700
* selector for more info)
701
* - caller script is the one that called this Blender_Run function;
702
* - called script is the argument to this function: fname;
703
* To mark scripts whose global dicts can't be freed right after
704
* the script execution (or better, 'first pass', since these scripts
705
* leave callbacks for gui or file/image selectors) we flag them. But to
706
* get a pointer to them we need to check which one is currently
707
* running (if none we're already at a spacescript). To make sure only
708
* the called script will have the SCRIPT_RUNNING flag on, we unset it
709
* for the caller script here: */
710
script = G.main->script.first;
712
if (script->flags & SCRIPT_RUNNING) break;
713
script = script->id.next;
716
if (script) script->flags &= ~SCRIPT_RUNNING; /* unset */
718
BPY_txt_do_python_Text(text); /* call new script */
720
if (script) script->flags |= SCRIPT_RUNNING; /* set */
722
if (!is_blender_text) free_libblock(&G.main->text, text);
724
return EXPP_incr_ret(Py_None);
727
static PyObject * Blender_UpdateMenus( PyObject * self )
730
BPyMenu_RemoveAllEntries();
732
if (BPyMenu_Init(1) == -1)
733
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
734
"invalid scripts dir");
736
Py_INCREF( Py_None );
740
/*****************************************************************************/
741
/* Function: initBlender */
742
/*****************************************************************************/
743
void M_Blender_Init( void )
746
PyObject *dict, *smode, *SpaceHandlers;
205
748
g_blenderdict = NULL;
207
/* TODO: create a docstring for the Blender module */
208
module = Py_InitModule3("Blender", Blender_methods, NULL);
210
types_InitAll(); /* set all our pytypes to &PyType_Type*/
212
dict = PyModule_GetDict (module);
750
module = Py_InitModule3( "Blender", Blender_methods,
751
"The main Blender module" );
753
types_InitAll( ); /* set all our pytypes to &PyType_Type */
755
SpaceHandlers = M_constant_New();
757
BPy_constant *d = (BPy_constant *)SpaceHandlers;
759
constant_insert(d,"VIEW3D_EVENT",PyInt_FromLong(SPACEHANDLER_VIEW3D_EVENT));
760
constant_insert(d,"VIEW3D_DRAW", PyInt_FromLong(SPACEHANDLER_VIEW3D_DRAW));
762
PyModule_AddObject(module, "SpaceHandlers", SpaceHandlers);
766
smode = PyString_FromString("background");
768
smode = PyString_FromString("interactive");
770
dict = PyModule_GetDict( module );
213
771
g_blenderdict = dict;
216
PyDict_SetItemString(dict, "bylink", Py_False);
218
PyDict_SetItemString(dict, "link", Py_None);
219
PyDict_SetItemString(dict, "event", PyString_FromString(""));
221
PyDict_SetItemString (dict, "Types", Types_Init());
222
PyDict_SetItemString (dict, "sys", sys_Init());
223
PyDict_SetItemString (dict, "Registry", Registry_Init());
224
PyDict_SetItemString (dict, "Scene", Scene_Init());
225
PyDict_SetItemString (dict, "Object", Object_Init());
226
PyDict_SetItemString (dict, "Material", Material_Init());
227
PyDict_SetItemString (dict, "Camera", Camera_Init());
228
PyDict_SetItemString (dict, "Lamp", Lamp_Init());
229
PyDict_SetItemString (dict, "Lattice", Lattice_Init());
230
PyDict_SetItemString (dict, "Curve", Curve_Init());
231
PyDict_SetItemString (dict, "Armature", Armature_Init());
232
PyDict_SetItemString (dict, "Ipo", Ipo_Init());
233
PyDict_SetItemString (dict, "IpoCurve", IpoCurve_Init());
234
PyDict_SetItemString (dict, "Metaball", Metaball_Init());
235
PyDict_SetItemString (dict, "Image", Image_Init());
236
PyDict_SetItemString (dict, "Window", Window_Init());
237
PyDict_SetItemString (dict, "Draw", Draw_Init());
238
PyDict_SetItemString (dict, "BGL", BGL_Init());
239
PyDict_SetItemString (dict, "Effect", Effect_Init());
240
PyDict_SetItemString (dict, "Text", Text_Init());
241
PyDict_SetItemString (dict, "World", World_Init());
242
PyDict_SetItemString (dict, "Texture", Texture_Init());
243
PyDict_SetItemString (dict, "NMesh", NMesh_Init());
244
PyDict_SetItemString (dict, "Noise", Noise_Init());
245
PyDict_SetItemString (dict, "Mathutils",Mathutils_Init());
246
PyDict_SetItemString (dict, "Library", Library_Init());
248
PyModule_AddIntConstant(module, "TRUE", 1);
249
PyModule_AddIntConstant(module, "FALSE", 0);
773
PyDict_SetItemString( dict, "bylink", EXPP_incr_ret_False() );
774
PyDict_SetItemString( dict, "link", EXPP_incr_ret ( Py_None ) );
775
PyDict_SetItemString( dict, "event", PyString_FromString( "" ) );
776
PyDict_SetItemString( dict, "mode", smode );
778
PyDict_SetItemString( dict, "Types", Types_Init( ) );
779
PyDict_SetItemString( dict, "sys", sys_Init( ) );
780
PyDict_SetItemString( dict, "Registry", Registry_Init( ) );
781
PyDict_SetItemString( dict, "Scene", Scene_Init( ) );
782
PyDict_SetItemString( dict, "Object", Object_Init( ) );
783
PyDict_SetItemString( dict, "Material", Material_Init( ) );
784
PyDict_SetItemString( dict, "Camera", Camera_Init( ) );
785
PyDict_SetItemString( dict, "Lamp", Lamp_Init( ) );
786
PyDict_SetItemString( dict, "Lattice", Lattice_Init( ) );
787
PyDict_SetItemString( dict, "Curve", Curve_Init( ) );
788
PyDict_SetItemString( dict, "Armature", Armature_Init( ) );
789
PyDict_SetItemString( dict, "Ipo", Ipo_Init( ) );
790
PyDict_SetItemString( dict, "IpoCurve", IpoCurve_Init( ) );
791
PyDict_SetItemString( dict, "Metaball", Metaball_Init( ) );
792
PyDict_SetItemString( dict, "Image", Image_Init( ) );
793
PyDict_SetItemString( dict, "Window", Window_Init( ) );
794
PyDict_SetItemString( dict, "Draw", Draw_Init( ) );
795
PyDict_SetItemString( dict, "BGL", BGL_Init( ) );
796
PyDict_SetItemString( dict, "Effect", Effect_Init( ) );
797
PyDict_SetItemString( dict, "Text", Text_Init( ) );
798
PyDict_SetItemString( dict, "Text3d", Text3d_Init( ) );
799
PyDict_SetItemString( dict, "World", World_Init( ) );
800
PyDict_SetItemString( dict, "Texture", Texture_Init( ) );
801
PyDict_SetItemString( dict, "NMesh", NMesh_Init( ) );
802
PyDict_SetItemString( dict, "Noise", Noise_Init( ) );
803
PyDict_SetItemString( dict, "Mathutils", Mathutils_Init( ) );
804
PyDict_SetItemString( dict, "Library", Library_Init( ) );
805
PyDict_SetItemString( dict, "Sound", Sound_Init( ) );
806
PyDict_SetItemString( dict, "CurNurb", CurNurb_Init( ) );
807
PyDict_SetItemString( dict, "BezTriple", BezTriple_Init( ) );
809
PyModule_AddIntConstant( module, "TRUE", 1 );
810
PyModule_AddIntConstant( module, "FALSE", 0 );