More work on render stuff!
[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                 scene_update_for_newframe(scene, scene->lay);
694         }
695
696         Py_INCREF( Py_None );
697         return Py_None;
698 }
699
700 //-----------------------Scene.update()----------------------------------
701 static PyObject *Scene_update( BPy_Scene * self, PyObject * args )
702 {
703         Scene *scene = self->scene;
704         int full = 0;
705
706         if( !scene )
707                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
708                                               "Blender Scene was deleted!" );
709
710         if( !PyArg_ParseTuple( args, "|i", &full ) )
711                 return EXPP_ReturnPyObjError( PyExc_TypeError,
712                                               "expected nothing or int (0 or 1) argument" );
713
714 /* Under certain circunstances, DAG_scene_sort *here* can crash Blender.
715  * A "RuntimeError: max recursion limit" happens when a scriptlink
716  * on frame change has scene.update(1).
717  * Investigate better how to avoid this. */
718         if( !full )
719                 DAG_scene_sort( scene );
720
721         else if( full == 1 )
722                 set_scene_bg( scene );
723
724         else
725                 return EXPP_ReturnPyObjError( PyExc_ValueError,
726                                               "in method scene.update(full), full should be:\n"
727                                               "0: to only sort scene elements (old behavior); or\n"
728                                               "1: for a full update (regroups, does ipos, keys, etc.)" );
729
730         Py_INCREF( Py_None );
731         return Py_None;
732 }
733
734 //-----------------------Scene.link()------------------------------------
735 static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
736 {
737         Scene *scene = self->scene;
738         BPy_Object *bpy_obj;
739         Object *object = NULL;
740
741         if( !scene )
742                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
743                                               "Blender Scene was deleted!" );
744
745         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
746                 return EXPP_ReturnPyObjError( PyExc_TypeError,
747                                               "expected Object argument" );
748         
749         
750                 //return EXPP_ReturnPyObjError( PyExc_RuntimeError,
751                 //                                "Could not create data on demand for this object type!" );
752         
753         object = bpy_obj->object;
754         
755         /* Object.c's EXPP_add_obdata does not support these objects */
756         if (!object->data && (object->type == OB_SURF || object->type == OB_FONT || object->type == OB_WAVE )) {
757                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
758                                               "Object has no data and new data cant be automaticaly created for Surf, Text or Wave type objects!" );
759         } else {
760                 /* Ok, all is fine, let's try to link it */
761                 Base *base;
762
763                 /* We need to link the object to a 'Base', then link this base
764                  * to the scene.        See DNA_scene_types.h ... */
765
766                 /* First, check if the object isn't already in the scene */
767                 base = EXPP_Scene_getObjectBase( scene, object );
768                 /* if base is not NULL ... */
769                 if( base )      /* ... the object is already in one of the Scene Bases */
770                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
771                                                       "object already in scene!" );
772
773                 /* not linked, go get mem for a new base object */
774
775                 base = MEM_callocN( sizeof( Base ), "pynewbase" );
776
777                 if( !base )
778                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
779                                                       "couldn't allocate new Base for object" );
780
781                 /* check if this object has obdata, case not, try to create it */
782                 
783                 if( !object->data && ( object->type != OB_EMPTY ) )
784                         EXPP_add_obdata( object ); /* returns -1 on error, defined in Object.c */
785
786                 base->object = object;  /* link object to the new base */
787                 base->lay = object->lay;
788                 base->flag = object->flag;
789
790                 object->id.us += 1;     /* incref the object user count in Blender */
791
792                 BLI_addhead( &scene->base, base );      /* finally, link new base to scene */
793         }
794
795         Py_INCREF( Py_None );
796         return Py_None;
797 }
798
799 //-----------------------Scene.unlink()----------------------------------
800 static PyObject *Scene_unlink( BPy_Scene * self, PyObject * args )
801 {
802         BPy_Object *bpy_obj = NULL;
803         Object *object;
804         Scene *scene = self->scene;
805         Base *base;
806         short retval = 0;
807
808         if( !scene )
809                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
810                                               "Blender scene was deleted!" );
811
812         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
813                 return EXPP_ReturnPyObjError( PyExc_TypeError,
814                                               "expected Object as argument" );
815
816         object = bpy_obj->object;
817
818         /* is the object really in the scene? */
819         base = EXPP_Scene_getObjectBase( scene, object );
820
821         if( base ) {            /* if it is, remove it: */
822                 BLI_remlink( &scene->base, base );
823                 object->id.us -= 1;
824                 MEM_freeN( base );
825                 scene->basact = 0;      /* in case the object was selected */
826                 retval = 1;
827         }
828
829         return Py_BuildValue( "i", PyInt_FromLong( retval ) );
830 }
831
832 //-----------------------Scene.getChildren()-----------------------------
833 static PyObject *Scene_getChildren( BPy_Scene * self )
834 {
835         Scene *scene = self->scene;
836         PyObject *pylist = PyList_New( 0 );
837         PyObject *bpy_obj;
838         Object *object;
839         Base *base;
840
841         if( !scene )
842                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
843                                               "Blender Scene was deleted!" );
844
845         base = scene->base.first;
846
847         while( base ) {
848                 object = base->object;
849                 
850                 bpy_obj = Object_CreatePyObject( object );
851                 
852                 if( !bpy_obj )
853                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
854                                                       "couldn't create new object wrapper" );
855
856                 PyList_Append( pylist, bpy_obj );
857                 Py_XDECREF( bpy_obj );  /* PyList_Append incref'ed it */
858                 
859                 base = base->next;
860         }
861
862         return pylist;
863 }
864
865 //-----------------------Scene.getActiveObject()------------------------
866 static PyObject *Scene_getActiveObject(BPy_Scene *self)
867 {
868         Scene *scene = self->scene;
869         PyObject *pyob;
870         Object *ob;
871
872         if (!scene)
873                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
874                         "Blender Scene was deleted!");
875
876         ob = ((scene->basact) ? (scene->basact->object) : 0);
877
878         if (ob) {
879                 pyob = Object_CreatePyObject( ob );
880
881                 if (!pyob)
882                         return EXPP_ReturnPyObjError(PyExc_MemoryError,
883                                         "couldn't create new object wrapper!");
884
885                 return pyob;
886         }
887
888         return EXPP_incr_ret(Py_None); /* no active object */
889 }
890
891 //-----------------------Scene.getCurrentCamera()------------------------
892 static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
893 {
894         Object *cam_obj;
895         PyObject *pyob;
896         Scene *scene = self->scene;
897         
898         if( !scene )
899                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
900                                               "Blender Scene was deleted!" );
901
902         cam_obj = scene->camera;
903
904         if( cam_obj ) {         /* if found, return a wrapper for it */
905                 pyob = Object_CreatePyObject( cam_obj );
906                 if (!pyob)
907                         return EXPP_ReturnPyObjError(PyExc_MemoryError,
908                                         "couldn't create new object wrapper!");
909                 return pyob;
910         }
911
912         Py_INCREF( Py_None );   /* none found */
913         return Py_None;
914 }
915
916 //-----------------------Scene.setCurrentCamera()------------------------
917 static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args )
918 {
919         Object *object;
920         BPy_Object *cam_obj;
921         Scene *scene = self->scene;
922
923         if( !scene )
924                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
925                                               "Blender Scene was deleted!" );
926
927         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &cam_obj ) )
928                 return EXPP_ReturnPyObjError( PyExc_TypeError,
929                                               "expected Camera Object as argument" );
930
931         object = cam_obj->object;
932         if( object->type != OB_CAMERA )
933                 return EXPP_ReturnPyObjError( PyExc_ValueError,
934                                               "expected Camera Object as argument" );
935
936         scene->camera = object; /* set the current Camera */
937
938         /* if this is the current scene, update its window now */
939         if( !G.background && scene == G.scene ) /* Traced a crash to redrawing while in background mode -Campbell */
940                 copy_view3d_lock( REDRAW );
941
942 /* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
943  * The same happens in bpython. */
944
945         Py_INCREF( Py_None );
946         return Py_None;
947 }
948
949 //-----------------------Scene.getRenderingContext()---------------------
950 static PyObject *Scene_getRenderingContext( BPy_Scene * self )
951 {
952         if( !self->scene )
953                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
954                                               "Blender Scene was deleted!" );
955
956         return RenderData_CreatePyObject( self->scene );
957 }
958
959 static PyObject *Scene_getRadiosityContext( BPy_Scene * self )
960 {
961         if( !self->scene )
962                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
963                                               "Blender Scene was deleted!" );
964
965         return Radio_CreatePyObject( self->scene );
966 }
967
968 /* scene.addScriptLink */
969 static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args )
970 {
971         Scene *scene = self->scene;
972         ScriptLink *slink = NULL;
973
974         if( !scene )
975                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
976                                               "Blender Scene was deleted!" );
977
978         slink = &( scene )->scriptlink;
979
980         return EXPP_addScriptLink( slink, args, 1 );
981 }
982
983 /* scene.clearScriptLinks */
984 static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args )
985 {
986         Scene *scene = self->scene;
987         ScriptLink *slink = NULL;
988
989         if( !scene )
990                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
991                                               "Blender Scene was deleted!" );
992
993         slink = &( scene )->scriptlink;
994
995         return EXPP_clearScriptLinks( slink, args );
996 }
997
998 /* scene.getScriptLinks */
999 static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args )
1000 {
1001         Scene *scene = self->scene;
1002         ScriptLink *slink = NULL;
1003         PyObject *ret = NULL;
1004
1005         if( !scene )
1006                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1007                                               "Blender Scene was deleted!" );
1008
1009         slink = &( scene )->scriptlink;
1010
1011         ret = EXPP_getScriptLinks( slink, args, 1 );
1012
1013         if( ret )
1014                 return ret;
1015         else
1016                 return NULL;
1017 }
1018
1019 static PyObject *Scene_play( BPy_Scene * self, PyObject * args )
1020 {
1021         Scene *scene = self->scene;
1022         int mode = 0, win = SPACE_VIEW3D;
1023         PyObject *ret = NULL;
1024         ScrArea *sa = NULL, *oldsa = curarea;
1025
1026         if( !scene )
1027                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1028                                               "Blender Scene was deleted!" );
1029
1030         if( !PyArg_ParseTuple( args, "|ii", &mode, &win ) )
1031                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1032                                               "expected nothing, or or two ints as arguments." );
1033
1034         if( mode < 0 || mode > 3 )
1035                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1036                                               "mode should be in range [0, 3]." );
1037
1038         switch ( win ) {
1039         case SPACE_VIEW3D:
1040         case SPACE_SEQ:
1041         case SPACE_IPO:
1042         case SPACE_ACTION:
1043         case SPACE_NLA:
1044         case SPACE_SOUND:
1045         case SPACE_BUTS:        /* from here they don't 'play', but ... */
1046         case SPACE_TEXT:        /* ... might be used as a timer. */
1047         case SPACE_SCRIPT:
1048         case SPACE_OOPS:
1049         case SPACE_IMAGE:
1050         case SPACE_IMASEL:
1051         case SPACE_INFO:
1052         case SPACE_FILE:
1053                 break;
1054         default:
1055                 win = SPACE_VIEW3D;
1056         }
1057
1058         /* we have to move to a proper win */
1059         sa = find_biggest_area_of_type( win );
1060         if( !sa && win != SPACE_VIEW3D )
1061                 sa = find_biggest_area_of_type( SPACE_VIEW3D );
1062
1063         if( !sa )
1064                 sa = find_biggest_area(  );
1065
1066         if( sa )
1067                 areawinset( sa->win );
1068
1069         /* play_anim returns 0 for normal exit or 1 if user canceled it */
1070         ret = Py_BuildValue( "i", play_anim( mode ) );
1071
1072         if( sa )
1073                 areawinset( oldsa->win );
1074
1075         return ret;
1076 }
1077
1078 static PyObject *Scene_getTimeLine( BPy_Scene *self ) 
1079 {
1080         BPy_TimeLine *tm= NULL;
1081
1082         tm= (BPy_TimeLine *) PyObject_NEW (BPy_TimeLine, &TimeLine_Type);
1083         if (!tm)
1084                 return EXPP_ReturnPyObjError (PyExc_MemoryError,
1085                                               "couldn't create BPy_TimeLine object");
1086         tm->marker_list= &(self->scene->markers);
1087         tm->sfra= (int) self->scene->r.sfra;
1088         tm->efra= (int) self->scene->r.efra;
1089
1090         return (PyObject *)tm;
1091 }
1092
1093