4f1ce26778d54b200a6eaf07efefb49506e893eb
[blender-staging.git] / source / blender / python / api2_2x / Scene.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano, Jacques Guignot, Joseph Gilbert,
29  * Campbell Barton, Ken Hughes
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 */
33 struct View3D;
34
35 #include "Scene.h" /*This must come first */
36
37 #include "BKE_global.h"
38 #include "BKE_main.h"
39 #include "MEM_guardedalloc.h"   /* for MEM_callocN */
40 #include "DNA_screen_types.h"   /* SPACE_VIEW3D, SPACE_SEQ */
41 #include "BKE_depsgraph.h"
42 #include "BKE_library.h"
43 #include "BKE_scene.h"
44 #include "BLI_blenlib.h"
45 #include "BSE_drawview.h"       /* for play_anim */
46 #include "BSE_headerbuttons.h"  /* for copy_scene */
47 #include "BIF_drawscene.h"      /* for set_scene */
48 #include "BIF_space.h"          /* for copy_view3d_lock() */
49 #include "BIF_screen.h"         /* curarea */
50 #include "mydevice.h"           /* for #define REDRAW */
51 #include "DNA_view3d_types.h"
52 #include "Object.h"
53 #include "Camera.h"
54 #include "gen_utils.h"
55 #include "sceneRender.h"
56 #include "sceneRadio.h"
57 #include "sceneTimeLine.h"
58
59
60 static Base *EXPP_Scene_getObjectBase( Scene * scene, Object * object );
61 PyObject *M_Object_Get( PyObject * self, PyObject * args ); /* from Object.c */
62
63 //----------------------------------- Python BPy_Scene defaults------------
64 #define EXPP_SCENE_FRAME_MAX 30000
65 #define EXPP_SCENE_RENDER_WINRESOLUTION_MIN 4
66 #define EXPP_SCENE_RENDER_WINRESOLUTION_MAX 10000
67 //-----------------------Python API function prototypes for the Scene module--
68 static PyObject *M_Scene_New( PyObject * self, PyObject * args,
69                               PyObject * keywords );
70 static PyObject *M_Scene_Get( PyObject * self, PyObject * args );
71 static PyObject *M_Scene_GetCurrent( PyObject * self );
72 static PyObject *M_Scene_Unlink( PyObject * self, PyObject * arg );
73 //-----------------------Scene module doc strings-----------------------------
74 static char M_Scene_doc[] = "The Blender.Scene submodule";
75 static char M_Scene_New_doc[] =
76         "(name = 'Scene') - Create a new Scene called 'name' in Blender.";
77 static char M_Scene_Get_doc[] =
78         "(name = None) - Return the scene called 'name'. If 'name' is None, return a list with all Scenes.";
79 static char M_Scene_GetCurrent_doc[] =
80         "() - Return the currently active Scene in Blender.";
81 static char M_Scene_Unlink_doc[] =
82         "(scene) - Unlink (delete) scene 'Scene' from Blender. (scene) is of type Blender scene.";
83 //----------------------Scene module method def----------------------------
84 struct PyMethodDef M_Scene_methods[] = {
85         {"New", ( PyCFunction ) M_Scene_New, METH_VARARGS | METH_KEYWORDS,
86          M_Scene_New_doc},
87         {"Get", M_Scene_Get, METH_VARARGS, M_Scene_Get_doc},
88         {"get", M_Scene_Get, METH_VARARGS, M_Scene_Get_doc},
89         {"GetCurrent", ( PyCFunction ) M_Scene_GetCurrent,
90          METH_NOARGS, M_Scene_GetCurrent_doc},
91         {"getCurrent", ( PyCFunction ) M_Scene_GetCurrent,
92          METH_NOARGS, M_Scene_GetCurrent_doc},
93         {"Unlink", M_Scene_Unlink, METH_VARARGS, M_Scene_Unlink_doc},
94         {"unlink", M_Scene_Unlink, METH_VARARGS, M_Scene_Unlink_doc},
95         {NULL, NULL, 0, NULL}
96 };
97 //-----------------------BPy_Scene  method declarations--------------------
98 static PyObject *Scene_getName( BPy_Scene * self );
99 static PyObject *Scene_setName( BPy_Scene * self, PyObject * arg );
100 static PyObject *Scene_getLayers( BPy_Scene * self );
101 static PyObject *Scene_setLayers( BPy_Scene * self, PyObject * arg );
102 static PyObject *Scene_setLayersMask( BPy_Scene * self, PyObject * arg );
103 static PyObject *Scene_copy( BPy_Scene * self, PyObject * arg );
104 static PyObject *Scene_makeCurrent( BPy_Scene * self );
105 static PyObject *Scene_update( BPy_Scene * self, PyObject * args );
106 static PyObject *Scene_link( BPy_Scene * self, PyObject * args );
107 static PyObject *Scene_unlink( BPy_Scene * self, PyObject * args );
108 static PyObject *Scene_getChildren( BPy_Scene * self );
109 static PyObject *Scene_getActiveObject(BPy_Scene *self);
110 static PyObject *Scene_getCurrentCamera( BPy_Scene * self );
111 static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args );
112 static PyObject *Scene_getRenderingContext( BPy_Scene * self );
113 static PyObject *Scene_getRadiosityContext( BPy_Scene * self );
114 static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args );
115 static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args );
116 static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args );
117 static PyObject *Scene_play( BPy_Scene * self, PyObject * args );
118 static PyObject *Scene_getTimeLine( BPy_Scene * self );
119
120
121 //internal
122 static void Scene_dealloc( BPy_Scene * self );
123 static int Scene_setAttr( BPy_Scene * self, char *name, PyObject * v );
124 static int Scene_compare( BPy_Scene * a, BPy_Scene * b );
125 static PyObject *Scene_getAttr( BPy_Scene * self, char *name );
126 static PyObject *Scene_repr( BPy_Scene * self );
127 //-----------------------BPy_Scene method def------------------------------
128 static PyMethodDef BPy_Scene_methods[] = {
129         /* name, method, flags, doc */
130         {"getName", ( PyCFunction ) Scene_getName, METH_NOARGS,
131          "() - Return Scene name"},
132         {"setName", ( PyCFunction ) Scene_setName, METH_VARARGS,
133          "(str) - Change Scene name"},
134         {"getLayers", ( PyCFunction ) Scene_getLayers, METH_NOARGS,
135          "() - Return a list of layers int indices which are set in this scene "},
136         {"setLayers", ( PyCFunction ) Scene_setLayers, METH_VARARGS,
137          "(layers) - Change layers which are set in this scene\n"
138          "(layers) - list of integers in the range [1, 20]."},
139         {"copy", ( PyCFunction ) Scene_copy, METH_VARARGS,
140          "(duplicate_objects = 1) - Return a copy of this scene\n"
141          "The optional argument duplicate_objects defines how the scene\n"
142          "children are duplicated:\n\t0: Link Objects\n\t1: Link Object Data"
143          "\n\t2: Full copy\n"},
144         {"makeCurrent", ( PyCFunction ) Scene_makeCurrent, METH_NOARGS,
145          "() - Make self the current scene"},
146         {"update", ( PyCFunction ) Scene_update, METH_VARARGS,
147          "(full = 0) - Update scene self.\n"
148          "full = 0: sort the base list of objects."
149          "full = 1: full update -- also regroups, does ipos, keys"},
150         {"link", ( PyCFunction ) Scene_link, METH_VARARGS,
151          "(obj) - Link Object obj to this scene"},
152         {"unlink", ( PyCFunction ) Scene_unlink, METH_VARARGS,
153          "(obj) - Unlink Object obj from this scene"},
154         {"getChildren", ( PyCFunction ) Scene_getChildren, METH_NOARGS,
155          "() - Return list of all objects linked to this scene"},
156         {"getActiveObject", (PyCFunction)Scene_getActiveObject, METH_NOARGS,
157          "() - Return this scene's active object"},
158         {"getCurrentCamera", ( PyCFunction ) Scene_getCurrentCamera,
159          METH_NOARGS,
160          "() - Return current active Camera"},
161         {"getScriptLinks", ( PyCFunction ) Scene_getScriptLinks, METH_VARARGS,
162          "(eventname) - Get a list of this scene's scriptlinks (Text names) "
163          "of the given type\n"
164          "(eventname) - string: FrameChanged, OnLoad, OnSave, Redraw or Render."},
165         {"addScriptLink", ( PyCFunction ) Scene_addScriptLink, METH_VARARGS,
166          "(text, evt) - Add a new scene scriptlink.\n"
167          "(text) - string: an existing Blender Text name;\n"
168          "(evt) string: FrameChanged, OnLoad, OnSave, Redraw or Render."},
169         {"clearScriptLinks", ( PyCFunction ) Scene_clearScriptLinks,
170          METH_VARARGS,
171          "() - Delete all scriptlinks from this scene.\n"
172          "([s1<,s2,s3...>]) - Delete specified scriptlinks from this scene."},
173         {"setCurrentCamera", ( PyCFunction ) Scene_setCurrentCamera,
174          METH_VARARGS,
175          "() - Set the currently active Camera"},
176         {"getRenderingContext", ( PyCFunction ) Scene_getRenderingContext,
177          METH_NOARGS,
178          "() - Get the rendering context for the scene and return it as a BPy_RenderData"},
179         {"getRadiosityContext", ( PyCFunction ) Scene_getRadiosityContext,
180          METH_NOARGS,
181          "() - Get the radiosity context for this scene."},
182         {"play", ( PyCFunction ) Scene_play, METH_VARARGS,
183          "(mode = 0, win = VIEW3D) - Play realtime animation in Blender"
184          " (not rendered).\n"
185          "(mode) - int:\n"
186          "\t0 - keep playing in biggest given 'win';\n"
187          "\t1 - keep playing in all 'win', VIEW3D and SEQ windows;\n"
188          "\t2 - play once in biggest given 'win';\n"
189          "\t3 - play once in all 'win', VIEW3D and SEQ windows.\n"
190          "(win) - int: see Blender.Window.Types. Only these are meaningful here:"
191          "VIEW3D, SEQ,  IPO, ACTION, NLA, SOUND.  But others are also accepted, "
192          "since they can be used just as an interruptible timer.  If 'win' is not"
193          "available or invalid, VIEW3D is tried, then any bigger window."
194          "Returns 0 for normal exit or 1 when canceled by user input."},
195         {"getTimeLine", ( PyCFunction ) Scene_getTimeLine, METH_NOARGS,
196         "() - Get time line of this Scene"},
197         {NULL, NULL, 0, NULL}
198 };
199 //-----------------------BPy_Scene method def------------------------------
200 PyTypeObject Scene_Type = {
201         PyObject_HEAD_INIT( NULL ) 
202         0,      /* ob_size */
203         "Scene",                /* tp_name */
204         sizeof( BPy_Scene ),    /* tp_basicsize */
205         0,                      /* tp_itemsize */
206         /* methods */
207         ( destructor ) Scene_dealloc,   /* tp_dealloc */
208         0,                      /* tp_print */
209         ( getattrfunc ) Scene_getAttr,  /* tp_getattr */
210         ( setattrfunc ) Scene_setAttr,  /* tp_setattr */
211         ( cmpfunc ) Scene_compare,      /* tp_compare */
212         ( reprfunc ) Scene_repr,        /* tp_repr */
213         0,                      /* tp_as_number */
214         0,                      /* tp_as_sequence */
215         0,                      /* tp_as_mapping */
216         0,                      /* tp_as_hash */
217         0, 0, 0, 0, 0, 0,
218         0,                      /* tp_doc */
219         0, 0, 0, 0, 0, 0,
220         BPy_Scene_methods,      /* tp_methods */
221         0,                      /* tp_members */
222         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
223 };
224 //-----------------------Scene module Init())-----------------------------
225 PyObject *Scene_Init( void )
226 {
227         PyObject *submodule;
228         PyObject *dict;
229
230         Scene_Type.ob_type = &PyType_Type;
231         submodule =
232                 Py_InitModule3( "Blender.Scene", M_Scene_methods,
233                                 M_Scene_doc );
234
235         dict = PyModule_GetDict( submodule );
236         PyDict_SetItemString( dict, "Render", Render_Init(  ) );
237         PyDict_SetItemString( dict, "Radio", Radio_Init(  ) );
238
239         return submodule;
240 }
241
242 //-----------------------Scene module internal callbacks------------------
243 //-----------------------dealloc------------------------------------------
244 static void Scene_dealloc( BPy_Scene * self )
245 {
246         PyObject_DEL( self );
247 }
248
249 //-----------------------getAttr----------------------------------------
250 static PyObject *Scene_getAttr( BPy_Scene * self, char *name )
251 {
252         PyObject *attr = Py_None;
253
254         if( strcmp( name, "name" ) == 0 )
255                 attr = PyString_FromString( self->scene->id.name + 2 );
256         /* accept both Layer (for compatibility with ob.Layer) and Layers */
257         else if( strncmp( name, "Layer", 5 ) == 0 )
258                 attr = PyInt_FromLong( self->scene->lay );
259         /* Layers returns a bitmask, layers returns a list of integers */
260         else if( strcmp( name, "layers") == 0) {
261                 return Scene_getLayers(self);
262         }
263
264         else if( strcmp( name, "__members__" ) == 0 )
265                 attr = Py_BuildValue( "[ss]", "name", "Layers", "layers" );
266
267         if( !attr )
268                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
269                                                 "couldn't create PyObject" ) );
270
271         if( attr != Py_None )
272                 return attr;    /* member attribute found, return it */
273
274         /* not an attribute, search the methods table */
275         return Py_FindMethod( BPy_Scene_methods, ( PyObject * ) self, name );
276 }
277
278 //-----------------------setAttr----------------------------------------
279 static int Scene_setAttr( BPy_Scene * self, char *name, PyObject * value )
280 {
281         PyObject *valtuple;
282         PyObject *error = NULL;
283
284 /* We're playing a trick on the Python API users here.  Even if they use
285  * Scene.member = val instead of Scene.setMember(val), we end up using the
286  * function anyway, since it already has error checking, clamps to the right
287  * interval and updates the Blender Scene structure when necessary. */
288
289 /* First we put "value" in a tuple, because we want to pass it to functions
290  * that only accept PyTuples. Using "N" doesn't increment value's ref count */
291         valtuple = Py_BuildValue( "(O)", value );
292
293         if( !valtuple )         /* everything OK with our PyObject? */
294                 return EXPP_ReturnIntError( PyExc_MemoryError,
295                                             "SceneSetAttr: couldn't create PyTuple" );
296
297 /* Now we just compare "name" with all possible BPy_Scene member variables */
298         if( strcmp( name, "name" ) == 0 )
299                 error = Scene_setName( self, valtuple );
300         else if (strncmp(name, "Layer", 5) == 0)
301                 error = Scene_setLayersMask(self, valtuple);    
302         else if (strcmp(name, "layers") == 0)
303                 error = Scene_setLayers(self, valtuple);
304
305         else { /* Error: no member with the given name was found */
306                 Py_DECREF( valtuple );
307                 return ( EXPP_ReturnIntError( PyExc_AttributeError, name ) );
308         }
309
310 /* valtuple won't be returned to the caller, so we need to DECREF it */
311         Py_DECREF( valtuple );
312
313         if( error != Py_None )
314                 return -1;
315
316 /* Py_None was incref'ed by the called Scene_set* function. We probably
317  * don't need to decref Py_None (!), but since Python/C API manual tells us
318  * to treat it like any other PyObject regarding ref counting ... */
319         Py_DECREF( Py_None );
320         return 0;               /* normal exit */
321 }
322
323 //-----------------------compare----------------------------------------
324 static int Scene_compare( BPy_Scene * a, BPy_Scene * b )
325 {
326         Scene *pa = a->scene, *pb = b->scene;
327         return ( pa == pb ) ? 0 : -1;
328 }
329
330 //----------------------repr--------------------------------------------
331 static PyObject *Scene_repr( BPy_Scene * self )
332 {
333         return PyString_FromFormat( "[Scene \"%s\"]",
334                                     self->scene->id.name + 2 );
335 }
336
337 //-----------------------CreatePyObject---------------------------------
338 PyObject *Scene_CreatePyObject( Scene * scene )
339 {
340         BPy_Scene *pyscene;
341
342         pyscene = ( BPy_Scene * ) PyObject_NEW( BPy_Scene, &Scene_Type );
343
344         if( !pyscene )
345                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
346                                               "couldn't create BPy_Scene object" );
347
348         pyscene->scene = scene;
349
350         return ( PyObject * ) pyscene;
351 }
352
353 //-----------------------CheckPyObject----------------------------------
354 int Scene_CheckPyObject( PyObject * pyobj )
355 {
356         return ( pyobj->ob_type == &Scene_Type );
357 }
358
359 //-----------------------FromPyObject-----------------------------------
360 Scene *Scene_FromPyObject( PyObject * pyobj )
361 {
362         return ( ( BPy_Scene * ) pyobj )->scene;
363 }
364
365 //-----------------------GetSceneByName()-------------------------------
366 /* Description: Returns the object with the name specified by the argument      name. 
367 Note that the calling function has to remove the first two characters of the object name. 
368 These two characters    specify the type of the object (OB, ME, WO, ...)The function 
369 will return NULL when no object with the given  name is found.   */
370 Scene *GetSceneByName( char *name )
371 {
372         Scene *scene_iter;
373
374         scene_iter = G.main->scene.first;
375         while( scene_iter ) {
376                 if( StringEqual( name, GetIdName( &( scene_iter->id ) ) ) ) {
377                         return ( scene_iter );
378                 }
379                 scene_iter = scene_iter->id.next;
380         }
381
382         /* There is no object with the given name */
383         return ( NULL );
384 }
385
386 //-----------------------EXPP_Scene_getObjectBase()---------------------
387 Base *EXPP_Scene_getObjectBase( Scene * scene, Object * object )
388 {
389         Base *base = scene->base.first;
390
391         while( base ) {
392
393                 if( object == base->object )
394                         return base;    /* found it? */
395
396                 base = base->next;
397         }
398
399         return NULL;            /* object isn't linked to this scene */
400 }
401
402 //-----------------------Scene module function defintions---------------
403 //-----------------------Scene.New()------------------------------------
404 static PyObject *M_Scene_New( PyObject * self, PyObject * args,
405                               PyObject * kword )
406 {
407         char *name = "Scene";
408         char *kw[] = { "name", NULL };
409         PyObject *pyscene;      /* for the Scene object wrapper in Python */
410         Scene *blscene;         /* for the actual Scene we create in Blender */
411
412         if( !PyArg_ParseTupleAndKeywords( args, kword, "|s", kw, &name ) )
413                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
414                                                 "expected a string or an empty argument list" ) );
415
416         blscene = add_scene( name );    /* first create the Scene in Blender */
417
418         if( blscene ) {
419                 /* normally, for most objects, we set the user count to zero here.
420                  * Scene is different than most objs since it is the container
421                  * for all the others. Since add_scene() has already set 
422                  * the user count to one, we leave it alone.
423                  */
424
425                 /* now create the wrapper obj in Python */
426                 pyscene = Scene_CreatePyObject( blscene );
427         } else
428                 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
429                                                 "couldn't create Scene obj in Blender" ) );
430
431         if( pyscene == NULL )
432                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
433                                                 "couldn't create Scene PyObject" ) );
434
435         return pyscene;
436 }
437
438 //-----------------------Scene.Get()------------------------------------
439 static PyObject *M_Scene_Get( PyObject * self, PyObject * args )
440 {
441         char *name = NULL;
442         Scene *scene_iter;
443
444         if( !PyArg_ParseTuple( args, "|s", &name ) )
445                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
446                                                 "expected string argument (or nothing)" ) );
447
448         scene_iter = G.main->scene.first;
449
450         if( name ) {            /* (name) - Search scene by name */
451
452                 PyObject *wanted_scene = NULL;
453
454                 while( ( scene_iter ) && ( wanted_scene == NULL ) ) {
455
456                         if( strcmp( name, scene_iter->id.name + 2 ) == 0 )
457                                 wanted_scene =
458                                         Scene_CreatePyObject( scene_iter );
459
460                         scene_iter = scene_iter->id.next;
461                 }
462
463                 if( wanted_scene == NULL ) {    /* Requested scene doesn't exist */
464                         char error_msg[64];
465                         PyOS_snprintf( error_msg, sizeof( error_msg ),
466                                        "Scene \"%s\" not found", name );
467                         return ( EXPP_ReturnPyObjError
468                                  ( PyExc_NameError, error_msg ) );
469                 }
470
471                 return wanted_scene;
472         }
473
474         else {  /* () - return a list with wrappers for all scenes in Blender */
475                 int index = 0;
476                 PyObject *sce_pylist, *pyobj;
477
478                 sce_pylist = PyList_New( BLI_countlist( &( G.main->scene ) ) );
479
480                 if( sce_pylist == NULL )
481                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
482                                                         "couldn't create PyList" ) );
483
484                 while( scene_iter ) {
485                         pyobj = Scene_CreatePyObject( scene_iter );
486
487                         if( !pyobj )
488                                 return ( EXPP_ReturnPyObjError
489                                          ( PyExc_MemoryError,
490                                            "couldn't create PyString" ) );
491
492                         PyList_SET_ITEM( sce_pylist, index, pyobj );
493
494                         scene_iter = scene_iter->id.next;
495                         index++;
496                 }
497
498                 return sce_pylist;
499         }
500 }
501
502 //-----------------------Scene.GetCurrent()------------------------------
503 static PyObject *M_Scene_GetCurrent( PyObject * self )
504 {
505         return Scene_CreatePyObject( ( Scene * ) G.scene );
506 }
507
508 //-----------------------Scene.Unlink()----------------------------------
509 static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
510 {
511         PyObject *pyobj;
512         Scene *scene;
513
514         if( !PyArg_ParseTuple( args, "O!", &Scene_Type, &pyobj ) )
515                 return EXPP_ReturnPyObjError( PyExc_TypeError,
516                                               "expected Scene PyType object" );
517
518         scene = ( ( BPy_Scene * ) pyobj )->scene;
519
520         if( scene == G.scene )
521                 return EXPP_ReturnPyObjError( PyExc_SystemError,
522                                               "current Scene cannot be removed!" );
523
524         free_libblock( &G.main->scene, scene );
525
526         Py_INCREF( Py_None );
527         return Py_None;
528 }
529
530 //-----------------------BPy_Scene function defintions-------------------
531 //-----------------------Scene.getName()---------------------------------
532 static PyObject *Scene_getName( BPy_Scene * self )
533 {
534         PyObject *attr = PyString_FromString( self->scene->id.name + 2 );
535
536         if( attr )
537                 return attr;
538
539         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
540                                         "couldn't get Scene.name attribute" ) );
541 }
542
543 //-----------------------Scene.setName()---------------------------------
544 static PyObject *Scene_setName( BPy_Scene * self, PyObject * args )
545 {
546         char *name;
547         char buf[21];
548
549         if( !PyArg_ParseTuple( args, "s", &name ) )
550                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
551                                                 "expected string argument" ) );
552
553         PyOS_snprintf( buf, sizeof( buf ), "%s", name );
554
555         rename_id( &self->scene->id, buf );
556
557         Py_INCREF( Py_None );
558         return Py_None;
559 }
560
561 //-----------------------Scene.getLayers()---------------------------------
562 static PyObject *Scene_getLayers( BPy_Scene * self )
563 {
564         PyObject *laylist = PyList_New( 0 ), *item;
565         int layers, bit = 0, val = 0;
566
567         if( !laylist )
568                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
569                         "couldn't create pylist!" ) );
570
571         layers = self->scene->lay;
572
573         while( bit < 20 ) {
574                 val = 1 << bit;
575                 if( layers & val ) {
576                         item = Py_BuildValue( "i", bit + 1 );
577                         PyList_Append( laylist, item );
578                         Py_DECREF( item );
579                 }
580                 bit++;
581         }
582         return laylist;
583 }
584
585 //-----------------------Scene.setLayers()---------------------------------
586 static PyObject *Scene_setLayers( BPy_Scene * self, PyObject * args )
587 {
588         PyObject *list = NULL, *item = NULL;
589         int layers = 0, val, i, len_list;
590
591         if( !PyArg_ParseTuple( args, "O!", &PyList_Type, &list ) )
592                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
593                         "expected a list of integers in the range [1, 20]" ) );
594
595         len_list = PyList_Size(list);
596
597         if (len_list == 0)
598                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
599                         "list can't be empty, at least one layer must be set" ) );
600
601         for( i = 0; i < len_list; i++ ) {
602                 item = PyList_GetItem( list, i );
603                 if( !PyInt_Check( item ) )
604                         return EXPP_ReturnPyObjError
605                                 ( PyExc_AttributeError,
606                                   "list must contain only integer numbers" );
607
608                 val = ( int ) PyInt_AsLong( item );
609                 if( val < 1 || val > 20 )
610                         return EXPP_ReturnPyObjError
611                                 ( PyExc_AttributeError,
612                                   "layer values must be in the range [1, 20]" );
613
614                 layers |= 1 << ( val - 1 );
615         }
616         self->scene->lay = layers;
617
618         if (G.vd && (self->scene == G.scene)) {
619                 int bit = 0;
620                 G.vd->lay = layers;
621
622                 while( bit < 20 ) {
623                         val = 1 << bit;
624                         if( layers & val ) {
625                                 G.vd->layact = val;
626                                 break;
627                         }
628                         bit++;
629                 }
630         }
631
632         return EXPP_incr_ret(Py_None);
633 }
634
635 /* only used by setAttr */
636 static PyObject *Scene_setLayersMask(BPy_Scene *self, PyObject *args)
637 {
638         int laymask = 0;
639
640         if (!PyArg_ParseTuple(args , "i", &laymask)) {
641                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
642                         "expected an integer (bitmask) as argument" );
643         }
644
645         if (laymask <= 0 || laymask > 1048575) /* binary: 1111 1111 1111 1111 1111 */
646                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
647                         "bitmask must have from 1 up to 20 bits set");
648
649         self->scene->lay = laymask;
650         /* if this is the current scene then apply the scene layers value
651          * to the view layers value: */
652         if (G.vd && (self->scene == G.scene)) {
653                 int val, bit = 0;
654                 G.vd->lay = laymask;
655
656                 while( bit < 20 ) {
657                         val = 1 << bit;
658                         if( laymask & val ) {
659                                 G.vd->layact = val;
660                                 break;
661                         }
662                         bit++;
663                 }
664         }
665
666         return EXPP_incr_ret(Py_None);
667 }
668
669 //-----------------------Scene.copy()------------------------------------
670 static PyObject *Scene_copy( BPy_Scene * self, PyObject * args )
671 {
672         short dup_objs = 1;
673         Scene *scene = self->scene;
674
675         if( !scene )
676                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
677                                               "Blender Scene was deleted!" );
678
679         if( !PyArg_ParseTuple( args, "|h", &dup_objs ) )
680                 return EXPP_ReturnPyObjError( PyExc_TypeError,
681                                               "expected int in [0,2] or nothing as argument" );
682
683         return Scene_CreatePyObject( copy_scene( scene, dup_objs ) );
684 }
685
686 //-----------------------Scene.makeCurrent()-----------------------------
687 static PyObject *Scene_makeCurrent( BPy_Scene * self )
688 {
689         Scene *scene = self->scene;
690
691         if( scene )
692                 set_scene( scene );
693
694         Py_INCREF( Py_None );
695         return Py_None;
696 }
697
698 //-----------------------Scene.update()----------------------------------
699 static PyObject *Scene_update( BPy_Scene * self, PyObject * args )
700 {
701         Scene *scene = self->scene;
702         int full = 0;
703
704         if( !scene )
705                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
706                                               "Blender Scene was deleted!" );
707
708         if( !PyArg_ParseTuple( args, "|i", &full ) )
709                 return EXPP_ReturnPyObjError( PyExc_TypeError,
710                                               "expected nothing or int (0 or 1) argument" );
711
712 /* Under certain circunstances, DAG_scene_sort *here* can crash Blender.
713  * A "RuntimeError: max recursion limit" happens when a scriptlink
714  * on frame change has scene.update(1).
715  * Investigate better how to avoid this. */
716         if( !full )
717                 DAG_scene_sort( scene );
718
719         else if( full == 1 )
720                 set_scene_bg( scene );
721
722         else
723                 return EXPP_ReturnPyObjError( PyExc_ValueError,
724                                               "in method scene.update(full), full should be:\n"
725                                               "0: to only sort scene elements (old behavior); or\n"
726                                               "1: for a full update (regroups, does ipos, keys, etc.)" );
727
728         Py_INCREF( Py_None );
729         return Py_None;
730 }
731
732 //-----------------------Scene.link()------------------------------------
733 static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
734 {
735         Scene *scene = self->scene;
736         BPy_Object *bpy_obj;
737         Object *object = NULL;
738
739         if( !scene )
740                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
741                                               "Blender Scene was deleted!" );
742
743         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
744                 return EXPP_ReturnPyObjError( PyExc_TypeError,
745                                               "expected Object argument" );
746         
747         
748                 //return EXPP_ReturnPyObjError( PyExc_RuntimeError,
749                 //                                "Could not create data on demand for this object type!" );
750         
751         object = bpy_obj->object;
752         
753         /* Object.c's EXPP_add_obdata does not support these objects */
754         if (!object->data && (object->type == OB_SURF || object->type == OB_FONT || object->type == OB_WAVE )) {
755                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
756                                               "Object has no data and new data cant be automaticaly created for Surf, Text or Wave type objects!" );
757         } else {
758                 /* Ok, all is fine, let's try to link it */
759                 Base *base;
760
761                 /* We need to link the object to a 'Base', then link this base
762                  * to the scene.        See DNA_scene_types.h ... */
763
764                 /* First, check if the object isn't already in the scene */
765                 base = EXPP_Scene_getObjectBase( scene, object );
766                 /* if base is not NULL ... */
767                 if( base )      /* ... the object is already in one of the Scene Bases */
768                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
769                                                       "object already in scene!" );
770
771                 /* not linked, go get mem for a new base object */
772
773                 base = MEM_callocN( sizeof( Base ), "pynewbase" );
774
775                 if( !base )
776                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
777                                                       "couldn't allocate new Base for object" );
778
779                 /* check if this object has obdata, case not, try to create it */
780                 
781                 if( !object->data && ( object->type != OB_EMPTY ) )
782                         EXPP_add_obdata( object ); /* returns -1 on error, defined in Object.c */
783
784                 base->object = object;  /* link object to the new base */
785                 base->lay = object->lay;
786                 base->flag = object->flag;
787
788                 object->id.us += 1;     /* incref the object user count in Blender */
789
790                 BLI_addhead( &scene->base, base );      /* finally, link new base to scene */
791         }
792
793         Py_INCREF( Py_None );
794         return Py_None;
795 }
796
797 //-----------------------Scene.unlink()----------------------------------
798 static PyObject *Scene_unlink( BPy_Scene * self, PyObject * args )
799 {
800         BPy_Object *bpy_obj = NULL;
801         Object *object;
802         Scene *scene = self->scene;
803         Base *base;
804         short retval = 0;
805
806         if( !scene )
807                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
808                                               "Blender scene was deleted!" );
809
810         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
811                 return EXPP_ReturnPyObjError( PyExc_TypeError,
812                                               "expected Object as argument" );
813
814         object = bpy_obj->object;
815
816         /* is the object really in the scene? */
817         base = EXPP_Scene_getObjectBase( scene, object );
818
819         if( base ) {            /* if it is, remove it: */
820                 BLI_remlink( &scene->base, base );
821                 object->id.us -= 1;
822                 MEM_freeN( base );
823                 scene->basact = 0;      /* in case the object was selected */
824                 retval = 1;
825         }
826
827         return Py_BuildValue( "i", PyInt_FromLong( retval ) );
828 }
829
830 //-----------------------Scene.getChildren()-----------------------------
831 static PyObject *Scene_getChildren( BPy_Scene * self )
832 {
833         Scene *scene = self->scene;
834         PyObject *pylist = PyList_New( 0 );
835         PyObject *bpy_obj;
836         Object *object;
837         Base *base;
838
839         if( !scene )
840                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
841                                               "Blender Scene was deleted!" );
842
843         base = scene->base.first;
844
845         while( base ) {
846                 object = base->object;
847                 
848                 bpy_obj = Object_CreatePyObject( object );
849                 
850                 if( !bpy_obj )
851                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
852                                                       "couldn't create new object wrapper" );
853
854                 PyList_Append( pylist, bpy_obj );
855                 Py_XDECREF( bpy_obj );  /* PyList_Append incref'ed it */
856                 
857                 base = base->next;
858         }
859
860         return pylist;
861 }
862
863 //-----------------------Scene.getActiveObject()------------------------
864 static PyObject *Scene_getActiveObject(BPy_Scene *self)
865 {
866         Scene *scene = self->scene;
867         PyObject *pyob;
868         Object *ob;
869
870         if (!scene)
871                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
872                         "Blender Scene was deleted!");
873
874         ob = ((scene->basact) ? (scene->basact->object) : 0);
875
876         if (ob) {
877                 pyob = Object_CreatePyObject( ob );
878
879                 if (!pyob)
880                         return EXPP_ReturnPyObjError(PyExc_MemoryError,
881                                         "couldn't create new object wrapper!");
882
883                 return pyob;
884         }
885
886         return EXPP_incr_ret(Py_None); /* no active object */
887 }
888
889 //-----------------------Scene.getCurrentCamera()------------------------
890 static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
891 {
892         Object *cam_obj;
893         PyObject *pyob;
894         Scene *scene = self->scene;
895         
896         if( !scene )
897                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
898                                               "Blender Scene was deleted!" );
899
900         cam_obj = scene->camera;
901
902         if( cam_obj ) {         /* if found, return a wrapper for it */
903                 pyob = Object_CreatePyObject( cam_obj );
904                 if (!pyob)
905                         return EXPP_ReturnPyObjError(PyExc_MemoryError,
906                                         "couldn't create new object wrapper!");
907                 return pyob;
908         }
909
910         Py_INCREF( Py_None );   /* none found */
911         return Py_None;
912 }
913
914 //-----------------------Scene.setCurrentCamera()------------------------
915 static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args )
916 {
917         Object *object;
918         BPy_Object *cam_obj;
919         Scene *scene = self->scene;
920
921         if( !scene )
922                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
923                                               "Blender Scene was deleted!" );
924
925         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &cam_obj ) )
926                 return EXPP_ReturnPyObjError( PyExc_TypeError,
927                                               "expected Camera Object as argument" );
928
929         object = cam_obj->object;
930         if( object->type != OB_CAMERA )
931                 return EXPP_ReturnPyObjError( PyExc_ValueError,
932                                               "expected Camera Object as argument" );
933
934         scene->camera = object; /* set the current Camera */
935
936         /* if this is the current scene, update its window now */
937         if( !G.background && scene == G.scene ) /* Traced a crash to redrawing while in background mode -Campbell */
938                 copy_view3d_lock( REDRAW );
939
940 /* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
941  * The same happens in bpython. */
942
943         Py_INCREF( Py_None );
944         return Py_None;
945 }
946
947 //-----------------------Scene.getRenderingContext()---------------------
948 static PyObject *Scene_getRenderingContext( BPy_Scene * self )
949 {
950         if( !self->scene )
951                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
952                                               "Blender Scene was deleted!" );
953
954         return RenderData_CreatePyObject( self->scene );
955 }
956
957 static PyObject *Scene_getRadiosityContext( BPy_Scene * self )
958 {
959         if( !self->scene )
960                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
961                                               "Blender Scene was deleted!" );
962
963         return Radio_CreatePyObject( self->scene );
964 }
965
966 /* scene.addScriptLink */
967 static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args )
968 {
969         Scene *scene = self->scene;
970         ScriptLink *slink = NULL;
971
972         if( !scene )
973                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
974                                               "Blender Scene was deleted!" );
975
976         slink = &( scene )->scriptlink;
977
978         return EXPP_addScriptLink( slink, args, 1 );
979 }
980
981 /* scene.clearScriptLinks */
982 static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args )
983 {
984         Scene *scene = self->scene;
985         ScriptLink *slink = NULL;
986
987         if( !scene )
988                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
989                                               "Blender Scene was deleted!" );
990
991         slink = &( scene )->scriptlink;
992
993         return EXPP_clearScriptLinks( slink, args );
994 }
995
996 /* scene.getScriptLinks */
997 static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args )
998 {
999         Scene *scene = self->scene;
1000         ScriptLink *slink = NULL;
1001         PyObject *ret = NULL;
1002
1003         if( !scene )
1004                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1005                                               "Blender Scene was deleted!" );
1006
1007         slink = &( scene )->scriptlink;
1008
1009         ret = EXPP_getScriptLinks( slink, args, 1 );
1010
1011         if( ret )
1012                 return ret;
1013         else
1014                 return NULL;
1015 }
1016
1017 static PyObject *Scene_play( BPy_Scene * self, PyObject * args )
1018 {
1019         Scene *scene = self->scene;
1020         int mode = 0, win = SPACE_VIEW3D;
1021         PyObject *ret = NULL;
1022         ScrArea *sa = NULL, *oldsa = curarea;
1023
1024         if( !scene )
1025                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1026                                               "Blender Scene was deleted!" );
1027
1028         if( !PyArg_ParseTuple( args, "|ii", &mode, &win ) )
1029                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1030                                               "expected nothing, or or two ints as arguments." );
1031
1032         if( mode < 0 || mode > 3 )
1033                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1034                                               "mode should be in range [0, 3]." );
1035
1036         switch ( win ) {
1037         case SPACE_VIEW3D:
1038         case SPACE_SEQ:
1039         case SPACE_IPO:
1040         case SPACE_ACTION:
1041         case SPACE_NLA:
1042         case SPACE_SOUND:
1043         case SPACE_BUTS:        /* from here they don't 'play', but ... */
1044         case SPACE_TEXT:        /* ... might be used as a timer. */
1045         case SPACE_SCRIPT:
1046         case SPACE_OOPS:
1047         case SPACE_IMAGE:
1048         case SPACE_IMASEL:
1049         case SPACE_INFO:
1050         case SPACE_FILE:
1051                 break;
1052         default:
1053                 win = SPACE_VIEW3D;
1054         }
1055
1056         /* we have to move to a proper win */
1057         sa = find_biggest_area_of_type( win );
1058         if( !sa && win != SPACE_VIEW3D )
1059                 sa = find_biggest_area_of_type( SPACE_VIEW3D );
1060
1061         if( !sa )
1062                 sa = find_biggest_area(  );
1063
1064         if( sa )
1065                 areawinset( sa->win );
1066
1067         /* play_anim returns 0 for normal exit or 1 if user canceled it */
1068         ret = Py_BuildValue( "i", play_anim( mode ) );
1069
1070         if( sa )
1071                 areawinset( oldsa->win );
1072
1073         return ret;
1074 }
1075
1076 static PyObject *Scene_getTimeLine( BPy_Scene *self ) 
1077 {
1078         BPy_TimeLine *tm= NULL;
1079
1080         tm= (BPy_TimeLine *) PyObject_NEW (BPy_TimeLine, &TimeLine_Type);
1081         if (!tm)
1082                 return EXPP_ReturnPyObjError (PyExc_MemoryError,
1083                                               "couldn't create BPy_TimeLine object");
1084         tm->marker_list= &(self->scene->markers);
1085         tm->sfra= (int) self->scene->r.sfra;
1086         tm->efra= (int) self->scene->r.efra;
1087
1088         return (PyObject *)tm;
1089 }
1090
1091