edb5e015eea10922b635f7648874e76623ca6dae
[blender.git] / source / blender / python / api2_2x / Scene.c
1 /* 
2  *
3  * $Id$
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * This is a new part of Blender.
25  *
26  * Contributor(s): Willian P. Germano, Jacques Guignot, Joseph Gilbert,
27  * Campbell Barton, Ken Hughes
28  *
29  * ***** END GPL LICENSE BLOCK *****
30 */
31 struct View3D;
32
33 #include "Scene.h" /*This must come first */
34
35 #include "BKE_global.h"
36 #include "BKE_main.h"
37 #include "MEM_guardedalloc.h"   /* for MEM_callocN */
38 #include "DNA_space_types.h"    /* SPACE_VIEW3D, SPACE_SEQ */
39 #include "DNA_screen_types.h"
40 #include "DNA_userdef_types.h" /* U.userdefs */
41 #include "DNA_object_types.h" /* SceneObSeq_new */
42 #include "BKE_armature.h"
43 #include "BKE_depsgraph.h"
44 #include "BKE_library.h"
45 #include "BKE_object.h"
46 #include "BKE_scene.h"
47 #include "BKE_font.h"
48 #include "BKE_idprop.h"
49 #include "BLI_blenlib.h" /* only for SceneObSeq_new */
50 #include "BSE_drawview.h"       /* for play_anim */
51 #include "BSE_headerbuttons.h"  /* for copy_scene */
52 #include "BSE_sequence.h"       /* to clear_scene_in_allseqs */
53 #include "BSE_node.h"   /* to clear_scene_in_nodes */
54 #include "BIF_drawscene.h"      /* for set_scene */
55 #include "BIF_space.h"          /* for copy_view3d_lock() */
56 #include "BIF_screen.h"         /* curarea */
57 #include "BDR_editobject.h"             /* free_and_unlink_base() */
58 #include "mydevice.h"           /* for #define REDRAW */
59 #include "DNA_view3d_types.h"
60
61 /* python types */
62 #include "Object.h"
63 #include "Camera.h"
64 /* only for SceneObSeq_new */
65 #include "BKE_material.h"
66 #include "BLI_arithb.h"
67 #include "Armature.h"
68 #include "Lamp.h"
69 #include "Curve.h"
70 #include "NMesh.h"
71 #include "Mesh.h"
72 #include "World.h"
73 #include "Lattice.h"
74 #include "Metaball.h"
75 #include "IDProp.h"
76 #include "Text3d.h"
77 #include "Library.h"
78
79 #include "gen_utils.h"
80 #include "gen_library.h"
81 #include "sceneRender.h"
82 #include "sceneRadio.h"
83 #include "sceneTimeLine.h"
84 #include "sceneSequence.h"
85
86
87 #include "BKE_utildefines.h" /* vec copy */
88 #include "vector.h"
89
90 PyObject *M_Object_Get( PyObject * self, PyObject * args ); /* from Object.c */
91
92 /* checks for the scene being removed */
93 #define SCENE_DEL_CHECK_PY(bpy_scene) if (!(bpy_scene->scene)) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "Scene has been removed" ) )
94 #define SCENE_DEL_CHECK_INT(bpy_scene) if (!(bpy_scene->scene)) return ( EXPP_ReturnIntError( PyExc_RuntimeError, "Scene has been removed" ) )
95
96
97 enum obj_consts {
98         EXPP_OBSEQ_NORMAL = 0,
99         EXPP_OBSEQ_SELECTED,
100         EXPP_OBSEQ_CONTEXT
101 };
102
103
104 /*-----------------------Python API function prototypes for the Scene module--*/
105 static PyObject *M_Scene_New( PyObject * self, PyObject * args,
106                               PyObject * keywords );
107 static PyObject *M_Scene_Get( PyObject * self, PyObject * args );
108 static PyObject *M_Scene_GetCurrent( PyObject * self );
109 static PyObject *M_Scene_getCurrent_deprecated( PyObject * self );
110 static PyObject *M_Scene_Unlink( PyObject * self, PyObject * arg );
111 /*-----------------------Scene module doc strings-----------------------------*/
112 static char M_Scene_doc[] = "The Blender.Scene submodule";
113 static char M_Scene_New_doc[] =
114         "(name = 'Scene') - Create a new Scene called 'name' in Blender.";
115 static char M_Scene_Get_doc[] =
116         "(name = None) - Return the scene called 'name'. If 'name' is None, return a list with all Scenes.";
117 static char M_Scene_GetCurrent_doc[] =
118         "() - Return the currently active Scene in Blender.";
119 static char M_Scene_Unlink_doc[] =
120         "(scene) - Unlink (delete) scene 'Scene' from Blender. (scene) is of type Blender scene.";
121 /*----------------------Scene module method def----------------------------*/
122 struct PyMethodDef M_Scene_methods[] = {
123         {"New", ( PyCFunction ) M_Scene_New, METH_VARARGS | METH_KEYWORDS,
124          M_Scene_New_doc},
125         {"Get", M_Scene_Get, METH_VARARGS, M_Scene_Get_doc},
126         {"get", M_Scene_Get, METH_VARARGS, M_Scene_Get_doc},
127         {"GetCurrent", ( PyCFunction ) M_Scene_GetCurrent,
128          METH_NOARGS, M_Scene_GetCurrent_doc},
129         {"getCurrent", ( PyCFunction ) M_Scene_getCurrent_deprecated,
130          METH_NOARGS, M_Scene_GetCurrent_doc},
131         {"Unlink", M_Scene_Unlink, METH_VARARGS, M_Scene_Unlink_doc},
132         {"unlink", M_Scene_Unlink, METH_VARARGS, M_Scene_Unlink_doc},
133         {NULL, NULL, 0, NULL}
134 };
135 /*-----------------------BPy_Scene  method declarations--------------------*/
136 static PyObject *Scene_getLayerList( BPy_Scene * self );
137 static PyObject *Scene_oldsetLayers( BPy_Scene * self, PyObject * arg );
138 static PyObject *Scene_copy( BPy_Scene * self, PyObject * arg );
139 static PyObject *Scene_makeCurrent( BPy_Scene * self );
140 static PyObject *Scene_update( BPy_Scene * self, PyObject * args );
141 static PyObject *Scene_link( BPy_Scene * self, PyObject * args );
142 static PyObject *Scene_unlink( BPy_Scene * self, PyObject * args );
143 static PyObject *Scene_getChildren( BPy_Scene * self );
144 static PyObject *Scene_getActiveObject(BPy_Scene *self);
145 static PyObject *Scene_getCurrentCamera( BPy_Scene * self );
146 static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args );
147 static PyObject *Scene_getRenderingContext( BPy_Scene * self );
148 static PyObject *Scene_getRadiosityContext( BPy_Scene * self );
149 static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * value );
150 static PyObject *Scene_getSequence( BPy_Scene * self );
151 static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args );
152 static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args );
153 static PyObject *Scene_play( BPy_Scene * self, PyObject * args );
154 static PyObject *Scene_getTimeLine( BPy_Scene * self );
155
156
157 /*internal*/
158 static int Scene_compare( BPy_Scene * a, BPy_Scene * b );
159 static PyObject *Scene_repr( BPy_Scene * self );
160
161 /*object seq*/
162 static PyObject *SceneObSeq_CreatePyObject( BPy_Scene *self, Base *iter, int mode);
163
164 /*-----------------------BPy_Scene method def------------------------------*/
165 static PyMethodDef BPy_Scene_methods[] = {
166         /* name, method, flags, doc */
167         {"getName", ( PyCFunction ) GenericLib_getName, METH_NOARGS,
168          "() - Return Scene name"},
169         {"setName", ( PyCFunction ) GenericLib_setName_with_method, METH_VARARGS,
170          "(str) - Change Scene name"},
171         {"getLayers", ( PyCFunction ) Scene_getLayerList, METH_NOARGS,
172          "() - Return a list of layers int indices which are set in this scene "},
173         {"setLayers", ( PyCFunction ) Scene_oldsetLayers, METH_VARARGS,
174          "(layers) - Change layers which are set in this scene\n"
175          "(layers) - list of integers in the range [1, 20]."},
176         {"copy", ( PyCFunction ) Scene_copy, METH_VARARGS,
177          "(duplicate_objects = 1) - Return a copy of this scene\n"
178          "The optional argument duplicate_objects defines how the scene\n"
179          "children are duplicated:\n\t0: Link Objects\n\t1: Link Object Data"
180          "\n\t2: Full copy\n"},
181         {"makeCurrent", ( PyCFunction ) Scene_makeCurrent, METH_NOARGS,
182          "() - Make self the current scene"},
183         {"update", ( PyCFunction ) Scene_update, METH_VARARGS,
184          "(full = 0) - Update scene self.\n"
185          "full = 0: sort the base list of objects."
186          "full = 1: full update -- also regroups, does ipos, keys"},
187         {"link", ( PyCFunction ) Scene_link, METH_VARARGS,
188          "(obj) - Link Object obj to this scene"},
189         {"unlink", ( PyCFunction ) Scene_unlink, METH_VARARGS,
190          "(obj) - Unlink Object obj from this scene"},
191         {"getChildren", ( PyCFunction ) Scene_getChildren, METH_NOARGS,
192          "() - Return list of all objects linked to this scene"},
193         {"getActiveObject", (PyCFunction)Scene_getActiveObject, METH_NOARGS,
194          "() - Return this scene's active object"},
195         {"getCurrentCamera", ( PyCFunction ) Scene_getCurrentCamera,
196          METH_NOARGS,
197          "() - Return current active Camera"},
198         {"getScriptLinks", ( PyCFunction ) Scene_getScriptLinks, METH_O,
199          "(eventname) - Get a list of this scene's scriptlinks (Text names) "
200          "of the given type\n"
201          "(eventname) - string: FrameChanged, OnLoad, OnSave, Redraw or Render."},
202         {"addScriptLink", ( PyCFunction ) Scene_addScriptLink, METH_VARARGS,
203          "(text, evt) - Add a new scene scriptlink.\n"
204          "(text) - string: an existing Blender Text name;\n"
205          "(evt) string: FrameChanged, OnLoad, OnSave, Redraw or Render."},
206         {"clearScriptLinks", ( PyCFunction ) Scene_clearScriptLinks,
207          METH_VARARGS,
208          "() - Delete all scriptlinks from this scene.\n"
209          "([s1<,s2,s3...>]) - Delete specified scriptlinks from this scene."},
210         {"setCurrentCamera", ( PyCFunction ) Scene_setCurrentCamera,
211          METH_VARARGS,
212          "() - Set the currently active Camera"},
213         {"getRenderingContext", ( PyCFunction ) Scene_getRenderingContext,
214          METH_NOARGS,
215          "() - Get the rendering context for the scene and return it as a BPy_RenderData"},
216         {"getRadiosityContext", ( PyCFunction ) Scene_getRadiosityContext,
217          METH_NOARGS,
218          "() - Get the radiosity context for this scene."},
219         {"play", ( PyCFunction ) Scene_play, METH_VARARGS,
220          "(mode = 0, win = VIEW3D) - Play realtime animation in Blender"
221          " (not rendered).\n"
222          "(mode) - int:\n"
223          "\t0 - keep playing in biggest given 'win';\n"
224          "\t1 - keep playing in all 'win', VIEW3D and SEQ windows;\n"
225          "\t2 - play once in biggest given 'win';\n"
226          "\t3 - play once in all 'win', VIEW3D and SEQ windows.\n"
227          "(win) - int: see Blender.Window.Types. Only these are meaningful here:"
228          "VIEW3D, SEQ,  IPO, ACTION, NLA, SOUND.  But others are also accepted, "
229          "since they can be used just as an interruptible timer.  If 'win' is not"
230          "available or invalid, VIEW3D is tried, then any bigger window."
231          "Returns 0 for normal exit or 1 when canceled by user input."},
232         {"getTimeLine", ( PyCFunction ) Scene_getTimeLine, METH_NOARGS,
233         "() - Get time line of this Scene"},
234         {NULL, NULL, 0, NULL}
235 };
236
237
238 /*****************************************************************************/
239 /* Python BPy_Scene getsetattr funcs:                                        */
240 /*****************************************************************************/
241 static PyObject *Scene_getLayerMask( BPy_Scene * self )
242 {
243         SCENE_DEL_CHECK_PY(self);
244         return PyInt_FromLong( self->scene->lay & ((1<<20)-1) );
245 }
246
247 static int Scene_setLayerMask( BPy_Scene * self, PyObject * value )
248 {
249         int laymask = 0;
250         
251         SCENE_DEL_CHECK_INT(self);
252         
253         if (!PyInt_Check(value)) {
254                 return EXPP_ReturnIntError( PyExc_AttributeError,
255                         "expected an integer (bitmask) as argument" );
256         }
257         
258         laymask = PyInt_AsLong(value);
259
260         if (laymask <= 0 || laymask > (1<<20) - 1) /* binary: 1111 1111 1111 1111 1111 */
261                 return EXPP_ReturnIntError( PyExc_AttributeError,
262                         "bitmask must have from 1 up to 20 bits set");
263
264         self->scene->lay = laymask;
265         /* if this is the current scene then apply the scene layers value
266          * to the view layers value: */
267         if (G.vd && (self->scene == G.scene)) {
268                 int val, bit = 0;
269                 G.vd->lay = laymask;
270
271                 while( bit < 20 ) {
272                         val = 1 << bit;
273                         if( laymask & val ) {
274                                 G.vd->layact = val;
275                                 break;
276                         }
277                         bit++;
278                 }
279         }
280
281         return 0;
282 }
283
284 static PyObject *Scene_getLayerList( BPy_Scene * self )
285 {
286         PyObject *laylist, *item;
287         int layers, bit = 0, val = 0;
288         
289         SCENE_DEL_CHECK_PY(self);
290         
291         laylist = PyList_New( 0 );
292         
293         if( !laylist )
294                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
295                         "couldn't create pylist!" ) );
296
297         layers = self->scene->lay;
298
299         while( bit < 20 ) {
300                 val = 1 << bit;
301                 if( layers & val ) {
302                         item = Py_BuildValue( "i", bit + 1 );
303                         PyList_Append( laylist, item );
304                         Py_DECREF( item );
305                 }
306                 bit++;
307         }
308         return laylist;
309 }
310
311 static int Scene_setLayerList( BPy_Scene * self, PyObject * value )
312 {
313         PyObject *item = NULL;
314         int layers = 0, val, i, len_list;
315         
316         SCENE_DEL_CHECK_INT(self);
317         
318         if( !PySequence_Check( value ) )
319                 return ( EXPP_ReturnIntError( PyExc_TypeError,
320                         "expected a list of integers in the range [1, 20]" ) );
321
322         len_list = PySequence_Size(value);
323
324         if (len_list == 0)
325                 return ( EXPP_ReturnIntError( PyExc_AttributeError,
326                         "list can't be empty, at least one layer must be set" ) );
327
328         for( i = 0; i < len_list; i++ ) {
329                 item = PySequence_GetItem( value, i );
330                 
331                 if( !PyInt_Check( item ) ) {
332                         Py_DECREF( item );
333                         return EXPP_ReturnIntError
334                                 ( PyExc_AttributeError,
335                                   "list must contain only integer numbers" );
336                 }
337                 
338                 val = ( int ) PyInt_AsLong( item );
339                 if( val < 1 || val > 20 )
340                         return EXPP_ReturnIntError
341                                 ( PyExc_AttributeError,
342                                   "layer values must be in the range [1, 20]" );
343
344                 layers |= 1 << ( val - 1 );
345         }
346         self->scene->lay = layers;
347
348         if (G.vd && (self->scene == G.scene)) {
349                 int bit = 0;
350                 G.vd->lay = layers;
351
352                 while( bit < 20 ) {
353                         val = 1 << bit;
354                         if( layers & val ) {
355                                 G.vd->layact = val;
356                                 break;
357                         }
358                         bit++;
359                 }
360         }
361
362         return 0;
363 }
364
365 static PyObject *Scene_getWorld( BPy_Scene * self )
366 {
367         SCENE_DEL_CHECK_PY(self);
368         
369         if (!self->scene->world)
370                 Py_RETURN_NONE;
371         return World_CreatePyObject(self->scene->world);
372 }
373
374 static int Scene_setWorld( BPy_Scene * self, PyObject * value )
375 {
376         SCENE_DEL_CHECK_INT(self);
377         return GenericLib_assignData(value, (void **) &self->scene->world, NULL, 1, ID_WO, 0);
378 }
379
380 /* accessed from scn.objects */
381 static PyObject *Scene_getObjects( BPy_Scene *self) 
382 {
383         SCENE_DEL_CHECK_PY(self);
384         return SceneObSeq_CreatePyObject(self, NULL, 0);
385 }
386
387 static PyObject *Scene_getCursor( BPy_Scene * self )
388 {
389         SCENE_DEL_CHECK_PY(self);
390         return newVectorObject( self->scene->cursor, 3, Py_WRAP );
391 }
392
393 static int Scene_setCursor( BPy_Scene * self, PyObject * value )
394 {       
395         VectorObject *bpy_vec;
396         SCENE_DEL_CHECK_INT(self);
397         if (!VectorObject_Check(value))
398                 return ( EXPP_ReturnIntError( PyExc_TypeError,
399                         "expected a vector" ) );
400         
401         bpy_vec = (VectorObject *)value;
402         
403         if (bpy_vec->size != 3)
404                 return ( EXPP_ReturnIntError( PyExc_ValueError,
405                         "can only assign a 3D vector" ) );
406         
407         VECCOPY(self->scene->cursor, bpy_vec->vec);
408         return 0;
409 }
410
411 /*****************************************************************************/
412 /* Python attributes get/set structure:                                      */
413 /*****************************************************************************/
414 static PyGetSetDef BPy_Scene_getseters[] = {
415         GENERIC_LIB_GETSETATTR,
416         {"Layers",
417          (getter)Scene_getLayerMask, (setter)Scene_setLayerMask,
418          "Scene layer bitmask",
419          NULL},
420         {"layers",
421          (getter)Scene_getLayerList, (setter)Scene_setLayerList,
422          "Scene layer list",
423          NULL},
424         {"world",
425          (getter)Scene_getWorld, (setter)Scene_setWorld,
426          "Scene layer bitmask",
427          NULL},
428         {"cursor",
429          (getter)Scene_getCursor, (setter)Scene_setCursor,
430          "Scene layer bitmask",
431          NULL},
432         {"timeline",
433          (getter)Scene_getTimeLine, (setter)NULL,
434          "Scenes timeline (read only)",
435          NULL},
436         {"render",
437          (getter)Scene_getRenderingContext, (setter)NULL,
438          "Scenes rendering context (read only)",
439          NULL},
440         {"radiosity",
441          (getter)Scene_getRadiosityContext, (setter)NULL,
442          "Scenes radiosity context (read only)",
443          NULL},
444         {"sequence",
445          (getter)Scene_getSequence, (setter)NULL,
446          "Scene sequencer data (read only)",
447          NULL},
448          
449         {"objects",
450          (getter)Scene_getObjects, (setter)NULL,
451          "Scene object iterator",
452          NULL},
453         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
454 };
455
456
457
458 /*-----------------------BPy_Scene method def------------------------------*/
459 PyTypeObject Scene_Type = {
460         PyObject_HEAD_INIT( NULL ) 
461         0,      /* ob_size */
462         "Scene",                /* tp_name */
463         sizeof( BPy_Scene ),    /* tp_basicsize */
464         0,                      /* tp_itemsize */
465         /* methods */
466         NULL,                                           /* tp_dealloc */
467         NULL,                       /* printfunc tp_print; */
468         NULL,                       /* getattrfunc tp_getattr; */
469         NULL,                       /* setattrfunc tp_setattr; */
470         ( cmpfunc ) Scene_compare,      /* tp_compare */
471         ( reprfunc ) Scene_repr,        /* tp_repr */
472
473         /* Method suites for standard classes */
474
475         NULL,                       /* PyNumberMethods *tp_as_number; */
476         NULL,                       /* PySequenceMethods *tp_as_sequence; */
477         NULL,                       /* PyMappingMethods *tp_as_mapping; */
478
479         /* More standard operations (here for binary compatibility) */
480
481         ( hashfunc ) GenericLib_hash,   /* hashfunc tp_hash; */
482         NULL,                       /* ternaryfunc tp_call; */
483         NULL,                       /* reprfunc tp_str; */
484         NULL,                       /* getattrofunc tp_getattro; */
485         NULL,                       /* setattrofunc tp_setattro; */
486
487         /* Functions to access object as input/output buffer */
488         NULL,                       /* PyBufferProcs *tp_as_buffer; */
489
490   /*** Flags to define presence of optional/expanded features ***/
491         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
492
493         NULL,                       /*  char *tp_doc;  Documentation string */
494   /*** Assigned meaning in release 2.0 ***/
495         /* call function for all accessible objects */
496         NULL,                       /* traverseproc tp_traverse; */
497
498         /* delete references to contained objects */
499         NULL,                       /* inquiry tp_clear; */
500
501   /***  Assigned meaning in release 2.1 ***/
502   /*** rich comparisons ***/
503         NULL,                       /* richcmpfunc tp_richcompare; */
504
505   /***  weak reference enabler ***/
506         0,                          /* long tp_weaklistoffset; */
507
508   /*** Added in release 2.2 ***/
509         /*   Iterators */
510         NULL,                       /* getiterfunc tp_iter; */
511         NULL,                       /* iternextfunc tp_iternext; */
512
513   /*** Attribute descriptor and subclassing stuff ***/
514         BPy_Scene_methods,           /* struct PyMethodDef *tp_methods; */
515         NULL,                       /* struct PyMemberDef *tp_members; */
516         BPy_Scene_getseters,         /* struct PyGetSetDef *tp_getset; */
517         NULL,                       /* struct _typeobject *tp_base; */
518         NULL,                       /* PyObject *tp_dict; */
519         NULL,                       /* descrgetfunc tp_descr_get; */
520         NULL,                       /* descrsetfunc tp_descr_set; */
521         0,                          /* long tp_dictoffset; */
522         NULL,                       /* initproc tp_init; */
523         NULL,                       /* allocfunc tp_alloc; */
524         NULL,                       /* newfunc tp_new; */
525         /*  Low-level free-memory routine */
526         NULL,                       /* freefunc tp_free;  */
527         /* For PyObject_IS_GC */
528         NULL,                       /* inquiry tp_is_gc;  */
529         NULL,                       /* PyObject *tp_bases; */
530         /* method resolution order */
531         NULL,                       /* PyObject *tp_mro;  */
532         NULL,                       /* PyObject *tp_cache; */
533         NULL,                       /* PyObject *tp_subclasses; */
534         NULL,                       /* PyObject *tp_weaklist; */
535         NULL
536 };
537
538 /*-----------------------Scene module Init())-----------------------------*/
539 PyObject *Scene_Init( void )
540 {
541
542         PyObject *submodule;
543         PyObject *dict;
544         
545         if( PyType_Ready( &Scene_Type ) < 0 )
546                 return NULL;
547         if( PyType_Ready( &SceneObSeq_Type ) < 0 )
548                 return NULL;
549         
550         submodule = Py_InitModule3( "Blender.Scene", M_Scene_methods, M_Scene_doc );
551
552         dict = PyModule_GetDict( submodule );
553         PyDict_SetItemString( dict, "Render", Render_Init(  ) );
554         PyDict_SetItemString( dict, "Radio", Radio_Init(  ) );
555         PyDict_SetItemString( dict, "Sequence", Sequence_Init(  ) );
556         PyDict_SetItemString( dict, "TimeLine", TimeLine_Init(  ) );
557         
558         return submodule;
559 }
560
561 /*-----------------------compare----------------------------------------*/
562 static int Scene_compare( BPy_Scene * a, BPy_Scene * b )
563 {
564         return ( a->scene == b->scene ) ? 0 : -1;
565 }
566
567 /*----------------------repr--------------------------------------------*/
568 static PyObject *Scene_repr( BPy_Scene * self )
569 {
570         if( !(self->scene) )
571                 return PyString_FromString( "[Scene - Removed]");
572         else
573                 return PyString_FromFormat( "[Scene \"%s\"]",
574                                         self->scene->id.name + 2 );
575 }
576
577 /*-----------------------CreatePyObject---------------------------------*/
578 PyObject *Scene_CreatePyObject( Scene * scene )
579 {
580         BPy_Scene *pyscene;
581
582         pyscene = ( BPy_Scene * ) PyObject_NEW( BPy_Scene, &Scene_Type );
583
584         if( !pyscene )
585                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
586                                               "couldn't create BPy_Scene object" );
587
588         pyscene->scene = scene;
589
590         return ( PyObject * ) pyscene;
591 }
592
593 /*-----------------------FromPyObject-----------------------------------*/
594 Scene *Scene_FromPyObject( PyObject * pyobj )
595 {
596         return ( ( BPy_Scene * ) pyobj )->scene;
597 }
598
599 /*-----------------------Scene module function defintions---------------*/
600 /*-----------------------Scene.New()------------------------------------*/
601 static PyObject *M_Scene_New( PyObject * self, PyObject * args,
602                               PyObject * kword )
603 {
604         char *name = "Scene";
605         char *kw[] = { "name", NULL };
606         PyObject *pyscene;      /* for the Scene object wrapper in Python */
607         Scene *blscene;         /* for the actual Scene we create in Blender */
608
609         if( !PyArg_ParseTupleAndKeywords( args, kword, "|s", kw, &name ) )
610                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
611                                                 "expected a string or an empty argument list" ) );
612
613         blscene = add_scene( name );    /* first create the Scene in Blender */
614
615         if( blscene ) {
616                 /* normally, for most objects, we set the user count to zero here.
617                  * Scene is different than most objs since it is the container
618                  * for all the others. Since add_scene() has already set 
619                  * the user count to one, we leave it alone.
620                  */
621
622                 /* now create the wrapper obj in Python */
623                 pyscene = Scene_CreatePyObject( blscene );
624         } else
625                 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
626                                                 "couldn't create Scene obj in Blender" ) );
627
628         if( pyscene == NULL )
629                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
630                                                 "couldn't create Scene PyObject" ) );
631
632         return pyscene;
633 }
634
635 /*-----------------------Scene.Get()------------------------------------*/
636 static PyObject *M_Scene_Get( PyObject * self, PyObject * args )
637 {
638         char *tname = NULL, name[22];
639         Scene *scene_iter;
640
641         if( !PyArg_ParseTuple( args, "|s", &tname ) )
642                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
643                                                 "expected string argument (or nothing)" ) );
644
645         strncpy(name, tname, 21);
646         if( strlen(tname) >= 21 ) name[21]= 0;
647         
648         scene_iter = G.main->scene.first;
649
650         if( tname ) {           /* (name) - Search scene by name */
651
652                 PyObject *wanted_scene = NULL;
653
654                 while( ( scene_iter ) && ( wanted_scene == NULL ) ) {
655
656                         if( strcmp( name, scene_iter->id.name + 2 ) == 0 )
657                                 wanted_scene =
658                                         Scene_CreatePyObject( scene_iter );
659
660                         scene_iter = scene_iter->id.next;
661                 }
662
663                 if( wanted_scene == NULL ) {    /* Requested scene doesn't exist */
664                         char error_msg[64];
665                         PyOS_snprintf( error_msg, sizeof( error_msg ),
666                                        "Scene \"%s\" not found", name );
667                         return ( EXPP_ReturnPyObjError
668                                  ( PyExc_NameError, error_msg ) );
669                 }
670
671                 return wanted_scene;
672         }
673
674         else {  /* () - return a list with wrappers for all scenes in Blender */
675                 int index = 0;
676                 PyObject *sce_pylist, *pyobj;
677
678                 sce_pylist = PyList_New( BLI_countlist( &( G.main->scene ) ) );
679
680                 if( sce_pylist == NULL )
681                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
682                                                         "couldn't create PyList" ) );
683
684                 while( scene_iter ) {
685                         pyobj = Scene_CreatePyObject( scene_iter );
686
687                         if( !pyobj ) {
688                                 Py_DECREF(sce_pylist);
689                                 return ( EXPP_ReturnPyObjError
690                                          ( PyExc_MemoryError,
691                                            "couldn't create PyString" ) );
692                         }
693                         PyList_SET_ITEM( sce_pylist, index, pyobj );
694
695                         scene_iter = scene_iter->id.next;
696                         index++;
697                 }
698
699                 return sce_pylist;
700         }
701 }
702
703 /*-----------------------Scene.GetCurrent()------------------------------*/
704 static PyObject *M_Scene_GetCurrent( PyObject * self )
705 {
706         return Scene_CreatePyObject( ( Scene * ) G.scene );
707 }
708
709 static PyObject *M_Scene_getCurrent_deprecated( PyObject * self )
710 {
711         static char warning = 1;
712         if( warning ) {
713                 printf("Blender.Scene.getCurrent() is deprecated,\n\tuse Blender.Scene.GetCurrent() instead.\n");
714                 --warning;
715         }
716
717         return Scene_CreatePyObject( ( Scene * ) G.scene );
718 }
719
720
721 /*-----------------------Scene.Unlink()----------------------------------*/
722 static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
723 {
724         PyObject *pyobj;
725         BPy_Scene *pyscn;
726         Scene *scene, *sce;
727         bScreen *sc;
728         
729         if( !PyArg_ParseTuple( args, "O!", &Scene_Type, &pyobj ) )
730                 return EXPP_ReturnPyObjError( PyExc_TypeError,
731                                               "expected Scene PyType object" );
732         
733         pyscn = (BPy_Scene *)pyobj;
734         scene = pyscn->scene;
735         
736         SCENE_DEL_CHECK_PY(pyscn);
737         
738         if( scene == G.scene )
739                 return EXPP_ReturnPyObjError( PyExc_SystemError,
740                                               "current Scene cannot be removed!" );
741
742         /* Copied from header_info.c */
743         
744         /* check all sets */
745         for (sce= G.main->scene.first; sce; sce= sce->id.next) {
746                 if(sce->set == scene) sce->set= 0;
747         }
748         
749         /* check all sequences */
750         clear_scene_in_allseqs(scene);
751
752         /* check render layer nodes in other scenes */
753         clear_scene_in_nodes(scene);
754         
755         for (sc= G.main->screen.first; sc; sc= sc->id.next ) {
756                 if(sc->scene == scene) sc->scene= G.scene;
757         }
758         
759         free_libblock( &G.main->scene, scene );
760         
761         pyscn->scene= NULL;
762         Py_RETURN_NONE;
763 }
764
765 /* DEPRECATE ME !!! */
766 /*-----------------------BPy_Scene function defintions-------------------*/
767
768 /*-----------------------Scene.setLayers()---------------------------------*/
769 static PyObject *Scene_oldsetLayers( BPy_Scene * self, PyObject * args )
770 {
771         return EXPP_setterWrapper( (void *)self, args, (setter)Scene_setLayerList );
772 }
773 /* END DEPRECATE CODE */
774
775
776 /*-----------------------Scene.copy()------------------------------------*/
777 static PyObject *Scene_copy( BPy_Scene * self, PyObject * args )
778 {
779         short dup_objs = 2;
780         Scene *scene = self->scene;
781
782         SCENE_DEL_CHECK_PY(self);
783
784         if( !PyArg_ParseTuple( args, "|h", &dup_objs ) || dup_objs < 0 || dup_objs > 2)
785                 return EXPP_ReturnPyObjError( PyExc_TypeError,
786                                               "expected int in [0,2] or nothing as argument" );
787         
788         return Scene_CreatePyObject( copy_scene( scene, dup_objs+1 ) );
789 }
790
791 /*-----------------------Scene.makeCurrent()-----------------------------*/
792 static PyObject *Scene_makeCurrent( BPy_Scene * self )
793 {
794         Scene *scene = self->scene;
795 #if 0   /* add back in when bpy becomes "official" */
796         static char warning = 1;
797         if( warning ) {
798                 printf("scene.makeCurrent() deprecated!\n\tuse bpy.scenes.active = scene instead\n");
799                 --warning;
800         }
801 #endif
802
803         SCENE_DEL_CHECK_PY(self);
804         
805         if( scene && scene != G.scene) {
806                 set_scene( scene );
807                 scene_update_for_newframe(scene, scene->lay);
808         }
809
810         Py_RETURN_NONE;
811 }
812
813 /*-----------------------Scene.update()----------------------------------*/
814 static PyObject *Scene_update( BPy_Scene * self, PyObject * args )
815 {
816         Scene *scene = self->scene;
817         int full = 0;
818         
819         SCENE_DEL_CHECK_PY(self);
820         if( !PyArg_ParseTuple( args, "|i", &full ) )
821                 return EXPP_ReturnPyObjError( PyExc_TypeError,
822                                               "expected nothing or int (0 or 1) argument" );
823
824 /* Under certain circunstances, DAG_scene_sort *here* can crash Blender.
825  * A "RuntimeError: max recursion limit" happens when a scriptlink
826  * on frame change has scene.update(1).
827  * Investigate better how to avoid this. */
828         if( !full )
829                 DAG_scene_sort( scene );
830
831         else if( full == 1 ) {
832                 int enablescripts = G.f & G_DOSCRIPTLINKS;
833                 
834                 /*Disable scriptlinks to prevent firing off newframe scriptlink
835                   events.*/
836                 G.f &= ~G_DOSCRIPTLINKS;
837                 set_scene_bg( scene );
838                 scene_update_for_newframe( scene, scene->lay );
839                 
840                 /*re-enabled scriptlinks if necassary.*/
841                 if (enablescripts) G.f |= G_DOSCRIPTLINKS;
842         } else
843                 return EXPP_ReturnPyObjError( PyExc_ValueError,
844                                               "in method scene.update(full), full should be:\n"
845                                               "0: to only sort scene elements (old behavior); or\n"
846                                               "1: for a full update (regroups, does ipos, keys, etc.)" );
847
848         Py_RETURN_NONE;
849 }
850
851 /*-----------------------Scene.link()------------------------------------*/
852 static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
853 {
854         Scene *scene = self->scene;
855         BPy_Object *bpy_obj;
856         Object *object = NULL;
857         static char warning = 1;
858
859         if( warning ) {
860                 printf("scene.link(ob) deprecated!\n\tuse scene.objects.link(ob) instead\n");
861                 --warning;
862         }
863
864         SCENE_DEL_CHECK_PY(self);
865         
866         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
867                 return EXPP_ReturnPyObjError( PyExc_TypeError,
868                                               "expected Object argument" );
869         
870         
871                 /*return EXPP_ReturnPyObjError( PyExc_RuntimeError,
872                                                   "Could not create data on demand for this object type!" );*/
873         
874         object = bpy_obj->object;
875         
876         /* Object.c's EXPP_add_obdata does not support these objects */
877         if (!object->data && (object->type == OB_SURF || object->type == OB_FONT || object->type == OB_WAVE )) {
878                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
879                                               "Object has no data and new data cant be automaticaly created for Surf, Text or Wave type objects!" );
880         } else {
881                 /* Ok, all is fine, let's try to link it */
882                 Base *base;
883
884                 /* We need to link the object to a 'Base', then link this base
885                  * to the scene.        See DNA_scene_types.h ... */
886
887                 /* First, check if the object isn't already in the scene */
888                 base = object_in_scene( object, scene );
889                 /* if base is not NULL ... */
890                 if( base )      /* ... the object is already in one of the Scene Bases */
891                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
892                                                       "object already in scene!" );
893
894                 /* not linked, go get mem for a new base object */
895
896                 base = MEM_callocN( sizeof( Base ), "pynewbase" );
897
898                 if( !base )
899                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
900                                                       "couldn't allocate new Base for object" );
901
902                 /*  if the object has not yet been linked to object data, then
903                  *  set the real type before we try creating data */
904
905                 if( bpy_obj->realtype != OB_EMPTY ) {
906                         object->type = bpy_obj->realtype;
907                         bpy_obj->realtype = OB_EMPTY;
908                 }
909
910                 /* check if this object has obdata, case not, try to create it */
911
912                 if( !object->data && ( object->type != OB_EMPTY ) )
913                         EXPP_add_obdata( object ); /* returns -1 on error, defined in Object.c */
914
915                 base->object = object;  /* link object to the new base */
916                 base->lay = object->lay;
917                 base->flag = object->flag;
918
919                 object->id.us += 1;     /* incref the object user count in Blender */
920
921                 BLI_addhead( &scene->base, base );      /* finally, link new base to scene */
922         }
923
924         Py_RETURN_NONE;
925 }
926
927 /*-----------------------Scene.unlink()----------------------------------*/
928 static PyObject *Scene_unlink( BPy_Scene * self, PyObject * args )
929 {
930         BPy_Object *bpy_obj = NULL;
931         Scene *scene = self->scene;
932         Base *base;
933         static char warning = 1;
934
935         if( warning ) {
936                 printf("scene.unlink(ob) deprecated!\n\tuse scene.objects.unlink(ob) instead\n");
937                 --warning;
938         }
939
940         SCENE_DEL_CHECK_PY(self);
941         
942         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
943                 return EXPP_ReturnPyObjError( PyExc_TypeError,
944                                               "expected Object as argument" );
945
946         /* is the object really in the scene? */
947         base = object_in_scene( bpy_obj->object, scene );
948
949         if( base ) {            /* if it is, remove it */
950                 if (scene->basact==base)
951                         scene->basact= NULL;    /* in case the object was selected */
952                 
953                 free_and_unlink_base_from_scene( scene, base );
954                 Py_RETURN_TRUE;
955         }
956         else
957                 Py_RETURN_FALSE;
958 }
959
960 /*-----------------------Scene.getChildren()-----------------------------*/
961 static PyObject *Scene_getChildren( BPy_Scene * self )
962 {
963         Scene *scene = self->scene;
964         PyObject *pylist;
965         PyObject *bpy_obj;
966         Object *object;
967         Base *base;
968         static char warning = 1;
969
970         if( warning ) {
971                 printf("scene.getChildren() deprecated!\n\tuse scene.objects instead\n");
972                 --warning;
973         }
974
975         SCENE_DEL_CHECK_PY(self);
976
977         pylist = PyList_New( 0 );
978         
979         base = scene->base.first;
980
981         while( base ) {
982                 object = base->object;
983                 
984                 bpy_obj = Object_CreatePyObject( object );
985                 
986                 if( !bpy_obj ) {
987                         Py_DECREF(pylist);
988                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
989                                                       "couldn't create new object wrapper" );
990                 }
991                 PyList_Append( pylist, bpy_obj );
992                 Py_DECREF( bpy_obj );   /* PyList_Append incref'ed it */
993                 
994                 base = base->next;
995         }
996
997         return pylist;
998 }
999
1000 /*-----------------------Scene.getActiveObject()------------------------*/
1001 static PyObject *Scene_getActiveObject(BPy_Scene *self)
1002 {
1003         Scene *scene = self->scene;
1004         PyObject *pyob;
1005         Object *ob;
1006         static char warning = 1;
1007
1008         if( warning ) {
1009                 printf("scene.getActiveObject() deprecated!\n\tuse scene.objects.active instead\n");
1010                 --warning;
1011         }
1012
1013         SCENE_DEL_CHECK_PY(self);
1014         
1015         ob = ((scene->basact) ? (scene->basact->object) : 0);
1016
1017         if (ob) {
1018                 pyob = Object_CreatePyObject( ob );
1019
1020                 if (!pyob)
1021                         return EXPP_ReturnPyObjError(PyExc_MemoryError,
1022                                         "couldn't create new object wrapper!");
1023
1024                 return pyob;
1025         }
1026
1027         Py_RETURN_NONE; /* no active object */
1028 }
1029
1030 /*-----------------------Scene.getCurrentCamera()------------------------*/
1031 static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
1032 {
1033         static char warning = 1;
1034         
1035         if( warning ) {
1036                 printf("scene.getCurrentCamera() deprecated!\n\tuse scene.objects.camera instead\n");
1037                 --warning;
1038         }
1039
1040         SCENE_DEL_CHECK_PY(self);
1041         /* None is ok */
1042         return Object_CreatePyObject( self->scene->camera );
1043 }
1044
1045 /*-----------------------Scene.setCurrentCamera()------------------------*/
1046 static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args )
1047 {
1048         Object *object;
1049         BPy_Object *cam_obj;
1050         Scene *scene = self->scene;
1051         static char warning = 1;
1052
1053         if( warning ) {
1054                 printf("scene.setCurrentCamera(ob) deprecated!\n\tSet scene.objects.camera = ob instead\n");
1055                 --warning;
1056         }
1057
1058         SCENE_DEL_CHECK_PY(self);
1059         
1060         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &cam_obj ) )
1061                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1062                                               "expected Camera Object as argument" );
1063
1064         object = cam_obj->object;
1065         if( object->type != OB_CAMERA )
1066                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1067                                               "expected Camera Object as argument" );
1068
1069         scene->camera = object; /* set the current Camera */
1070
1071         /* if this is the current scene, update its window now */
1072         if( !G.background && scene == G.scene ) /* Traced a crash to redrawing while in background mode -Campbell */
1073                 copy_view3d_lock( REDRAW );
1074
1075 /* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
1076  * The same happens in bpython. */
1077
1078         Py_RETURN_NONE;
1079 }
1080
1081 /*-----------------------Scene.getRenderingContext()---------------------*/
1082 static PyObject *Scene_getRenderingContext( BPy_Scene * self )
1083 {
1084         SCENE_DEL_CHECK_PY(self);
1085         return RenderData_CreatePyObject( self->scene );
1086 }
1087
1088 static PyObject *Scene_getRadiosityContext( BPy_Scene * self )
1089 {
1090         SCENE_DEL_CHECK_PY(self);
1091         return Radio_CreatePyObject( self->scene );
1092 }
1093
1094 static PyObject *Scene_getSequence( BPy_Scene * self )
1095 {
1096         SCENE_DEL_CHECK_PY(self);
1097         return SceneSeq_CreatePyObject( self->scene, NULL );
1098 }
1099
1100 /* scene.addScriptLink */
1101 static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args )
1102 {
1103         Scene *scene = self->scene;
1104         ScriptLink *slink = NULL;
1105
1106         SCENE_DEL_CHECK_PY(self);
1107
1108         slink = &( scene )->scriptlink;
1109
1110         return EXPP_addScriptLink( slink, args, 1 );
1111 }
1112
1113 /* scene.clearScriptLinks */
1114 static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args )
1115 {
1116         Scene *scene = self->scene;
1117         ScriptLink *slink = NULL;
1118
1119         SCENE_DEL_CHECK_PY(self);
1120
1121         slink = &( scene )->scriptlink;
1122
1123         return EXPP_clearScriptLinks( slink, args );
1124 }
1125
1126 /* scene.getScriptLinks */
1127 static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * value )
1128 {
1129         Scene *scene = self->scene;
1130         ScriptLink *slink = NULL;
1131         PyObject *ret = NULL;
1132
1133         SCENE_DEL_CHECK_PY(self);
1134
1135         slink = &( scene )->scriptlink;
1136
1137         ret = EXPP_getScriptLinks( slink, value, 1 );
1138
1139         if( ret )
1140                 return ret;
1141         else
1142                 return NULL;
1143 }
1144
1145 static PyObject *Scene_play( BPy_Scene * self, PyObject * args )
1146 {
1147         int mode = 0, win = SPACE_VIEW3D;
1148         PyObject *ret = NULL;
1149         ScrArea *sa = NULL, *oldsa = curarea;
1150
1151         SCENE_DEL_CHECK_PY(self);
1152
1153         if( !PyArg_ParseTuple( args, "|ii", &mode, &win ) )
1154                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1155                                               "expected nothing, or or two ints as arguments." );
1156
1157         if( mode < 0 || mode > 3 )
1158                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1159                                               "mode should be in range [0, 3]." );
1160
1161         switch ( win ) {
1162         case SPACE_VIEW3D:
1163         case SPACE_SEQ:
1164         case SPACE_IPO:
1165         case SPACE_ACTION:
1166         case SPACE_NLA:
1167         case SPACE_SOUND:
1168         case SPACE_BUTS:        /* from here they don't 'play', but ... */
1169         case SPACE_TEXT:        /* ... might be used as a timer. */
1170         case SPACE_SCRIPT:
1171         case SPACE_OOPS:
1172         case SPACE_IMAGE:
1173         case SPACE_IMASEL:
1174         case SPACE_INFO:
1175         case SPACE_FILE:
1176                 break;
1177         default:
1178                 win = SPACE_VIEW3D;
1179         }
1180
1181         /* we have to move to a proper win */
1182         sa = find_biggest_area_of_type( win );
1183         if( !sa && win != SPACE_VIEW3D )
1184                 sa = find_biggest_area_of_type( SPACE_VIEW3D );
1185
1186         if( !sa )
1187                 sa = find_biggest_area(  );
1188
1189         if( sa )
1190                 areawinset( sa->win );
1191
1192         /* play_anim returns 0 for normal exit or 1 if user canceled it */
1193         ret = PyInt_FromLong( (long)play_anim( mode ) );
1194
1195         if( sa )
1196                 areawinset( oldsa->win );
1197
1198         return ret;
1199 }
1200
1201 static PyObject *Scene_getTimeLine( BPy_Scene *self ) 
1202 {
1203         BPy_TimeLine *tm; 
1204
1205         SCENE_DEL_CHECK_PY(self);
1206         
1207         tm= (BPy_TimeLine *) PyObject_NEW (BPy_TimeLine, &TimeLine_Type);
1208         if (!tm)
1209                 return EXPP_ReturnPyObjError (PyExc_MemoryError,
1210                                               "couldn't create BPy_TimeLine object");
1211         tm->marker_list= &(self->scene->markers);
1212         tm->sfra= (int) self->scene->r.sfra;
1213         tm->efra= (int) self->scene->r.efra;
1214
1215         return (PyObject *)tm;
1216 }
1217
1218 /************************************************************************
1219  *
1220  * Object Sequence 
1221  *
1222  ************************************************************************/
1223 /*
1224  * create a thin wrapper for the scenes objects
1225  */
1226
1227 /* accessed from scn.objects.selected or scn.objects.context */
1228 static PyObject *SceneObSeq_getObjects( BPy_SceneObSeq *self, void *mode) 
1229 {
1230         SCENE_DEL_CHECK_PY(self->bpyscene);
1231         return SceneObSeq_CreatePyObject(self->bpyscene, NULL, (int)((long)mode));
1232 }
1233
1234 int SceneObSeq_setObjects( BPy_SceneObSeq *self, PyObject *value, void *_mode_) 
1235 {
1236         /*
1237         ONLY SUPPORTS scn.objects.selected and scn.objects.context 
1238         cannot assign to scn.objects yet!!!
1239         */
1240         PyObject *item;
1241         Scene *scene= self->bpyscene->scene;
1242         Object *blen_ob;
1243         Base *base;
1244         int size, mode = GET_INT_FROM_POINTER(_mode_);
1245         
1246         SCENE_DEL_CHECK_INT(self->bpyscene);
1247         
1248         /* scn.objects.selected = scn.objects  - shortcut to select all */
1249         if (BPy_SceneObSeq_Check(value)) {
1250                 BPy_SceneObSeq *bpy_sceneseq = (BPy_SceneObSeq *)value;
1251                 if (self->bpyscene->scene != bpy_sceneseq->bpyscene->scene)
1252                         return EXPP_ReturnIntError( PyExc_ValueError,
1253                                         "Cannot assign a SceneObSeq type from another scene" );
1254                 if (bpy_sceneseq->mode != EXPP_OBSEQ_NORMAL)
1255                         return EXPP_ReturnIntError( PyExc_ValueError,
1256                                         "Can only assign scn.objects to scn.objects.context or scn.objects.selected" );
1257                 
1258                 for (base= scene->base.first; base; base= base->next) {
1259                         base->flag |= SELECT;
1260                         base->object->flag |= SELECT;
1261                         
1262                         if (mode==EXPP_OBSEQ_CONTEXT && G.vd) {
1263                                 base->object->lay= base->lay= G.vd->lay;
1264                         }
1265                 }
1266                 return 0;
1267         }
1268
1269         if (!PySequence_Check(value))
1270                 return EXPP_ReturnIntError( PyExc_ValueError,
1271                                 "Error, must assign a sequence of objects to scn.objects.selected" );
1272         
1273         /* for context and selected, just deselect, dont remove */
1274         for (base= scene->base.first; base; base= base->next) {
1275                 base->flag &= ~SELECT;
1276                 base->object->flag &= ~SELECT;
1277         }
1278         
1279         size = PySequence_Length(value);
1280         while (size) {
1281                 size--;
1282                 item = PySequence_GetItem(value, size);
1283                 if ( PyObject_TypeCheck(item, &Object_Type) ) {
1284                         blen_ob= ((BPy_Object *)item)->object;
1285                         base = object_in_scene( blen_ob, scene );
1286                         if (base) {
1287                                 blen_ob->flag |= SELECT;
1288                                 base->flag |= SELECT;
1289                                 if (mode==EXPP_OBSEQ_CONTEXT && G.vd) {
1290                                         blen_ob->restrictflag &= ~OB_RESTRICT_VIEW;
1291                                         blen_ob->lay= base->lay= G.vd->lay;
1292                                 }
1293                         }
1294                 }
1295                 Py_DECREF(item);
1296         }
1297         return 0;
1298 }
1299
1300
1301 static PyObject *SceneObSeq_CreatePyObject( BPy_Scene *self, Base *iter, int mode )
1302 {
1303         BPy_SceneObSeq *seq = PyObject_NEW( BPy_SceneObSeq, &SceneObSeq_Type);
1304         seq->bpyscene = self; Py_INCREF(self);
1305         seq->iter = iter;
1306         seq->mode = mode;
1307         return (PyObject *)seq;
1308 }
1309
1310 static int SceneObSeq_len( BPy_SceneObSeq * self )
1311 {
1312         Scene *scene= self->bpyscene->scene;
1313         SCENE_DEL_CHECK_INT(self->bpyscene);
1314         
1315         if (self->mode == EXPP_OBSEQ_NORMAL)
1316                 return BLI_countlist( &( scene->base ) );
1317         else if (self->mode == EXPP_OBSEQ_SELECTED) {
1318                 int len=0;
1319                 Base *base;
1320                 for (base= scene->base.first; base; base= base->next) {
1321                         if (base->flag & SELECT) {
1322                                 len++;
1323                         }
1324                 }
1325                 return len;
1326         } else if (self->mode == EXPP_OBSEQ_CONTEXT) {
1327                 int len=0;
1328                 Base *base;
1329                 
1330                 if( G.vd == NULL ) /* No 3d view has been initialized yet, simply return an empty list */
1331                         return 0;
1332                 
1333                 for (base= scene->base.first; base; base= base->next) {
1334                         if TESTBASE(base) {
1335                                 len++;
1336                         }
1337                 }
1338                 return len;
1339         }
1340         /*should never run this */
1341         return 0;
1342 }
1343
1344 /*
1345  * retrive a single Object from somewhere in the Object list
1346  */
1347
1348 static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i )
1349 {
1350         int index=0;
1351         Base *base= NULL;
1352         Scene *scene= self->bpyscene->scene;
1353         
1354         SCENE_DEL_CHECK_PY(self->bpyscene);
1355         
1356         /* objects */
1357         if (self->mode==EXPP_OBSEQ_NORMAL)
1358                 for (base= scene->base.first; base && i!=index; base= base->next, index++) {}
1359         /* selected */
1360         else if (self->mode==EXPP_OBSEQ_SELECTED) {
1361                 for (base= scene->base.first; base; base= base->next) {
1362                         if (base->flag & SELECT) {
1363                                 if (i==index) {
1364                                         break;
1365                                 } else {
1366                                         index++;
1367                                 }
1368                         }
1369                 }
1370         }
1371         /* context */
1372         else if (self->mode==EXPP_OBSEQ_CONTEXT) {
1373                 if (G.vd) {
1374                         for (base= scene->base.first; base; base= base->next) {
1375                                 if (TESTBASE(base)) {
1376                                         if (i==index) {
1377                                                 break;
1378                                         } else {
1379                                                 index++;
1380                                         }
1381                                 }
1382                         }
1383                 }
1384         }
1385         
1386         if (!(base))
1387                 return EXPP_ReturnPyObjError( PyExc_IndexError,
1388                                               "array index out of range" );
1389         
1390         return Object_CreatePyObject( base->object );
1391 }
1392
1393 static PySequenceMethods SceneObSeq_as_sequence = {
1394         ( inquiry ) SceneObSeq_len,     /* sq_length */
1395         ( binaryfunc ) 0,       /* sq_concat */
1396         ( intargfunc ) 0,       /* sq_repeat */
1397         ( intargfunc ) SceneObSeq_item, /* sq_item */
1398         ( intintargfunc ) 0,    /* sq_slice */
1399         ( intobjargproc ) 0,    /* sq_ass_item */
1400         ( intintobjargproc ) 0, /* sq_ass_slice */
1401         0,0,0,
1402 };
1403
1404
1405 /************************************************************************
1406  *
1407  * Python SceneObSeq_Type iterator (iterates over GroupObjects)
1408  *
1409  ************************************************************************/
1410
1411 /*
1412  * Initialize the interator index
1413  */
1414
1415 static PyObject *SceneObSeq_getIter( BPy_SceneObSeq * self )
1416 {
1417         /* we need to get the first base, but for selected context we may need to advance
1418         to the first selected or first conext base */
1419         Base *base= self->bpyscene->scene->base.first;
1420         
1421         SCENE_DEL_CHECK_PY(self->bpyscene);
1422         
1423         if (self->mode==EXPP_OBSEQ_SELECTED)
1424                 while (base && !(base->flag & SELECT))
1425                         base= base->next;
1426         else if (self->mode==EXPP_OBSEQ_CONTEXT) {
1427                 if (!G.vd)
1428                         base= NULL; /* will never iterate if we have no */
1429                 else
1430                         while (base && !TESTBASE(base))
1431                                 base= base->next;       
1432         }
1433         /* create a new iterator if were alredy using this one */
1434         if (self->iter==NULL) {
1435                 self->iter = base;
1436                 return EXPP_incr_ret ( (PyObject *) self );
1437         } else {
1438                 return SceneObSeq_CreatePyObject(self->bpyscene, base, self->mode);
1439         }
1440 }
1441
1442 /*
1443  * Return next SceneOb.
1444  */
1445
1446 static PyObject *SceneObSeq_nextIter( BPy_SceneObSeq * self )
1447 {
1448         PyObject *object;
1449         Base *base;
1450         if( !(self->iter) ||  !(self->bpyscene->scene) ) {
1451                 self->iter= NULL;
1452                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
1453                                 "iterator at end" );
1454         }
1455         
1456         object= Object_CreatePyObject( self->iter->object ); 
1457         base= self->iter->next;
1458         
1459         if (self->mode==EXPP_OBSEQ_SELECTED)
1460                 while (base && !(base->flag & SELECT))
1461                         base= base->next;
1462         else if (self->mode==EXPP_OBSEQ_CONTEXT) {
1463                 if (!G.vd)
1464                         base= NULL; /* will never iterate if we have no */
1465                 else
1466                         while (base && !TESTBASE(base))
1467                                 base= base->next;       
1468         }
1469         self->iter= base;
1470         return object;
1471 }
1472
1473
1474 static PyObject *SceneObSeq_link( BPy_SceneObSeq * self, PyObject *pyobj )
1475 {       
1476         SCENE_DEL_CHECK_PY(self->bpyscene);
1477         
1478         /* this shold eventually replace Scene_link */
1479         if (self->mode != EXPP_OBSEQ_NORMAL)
1480                 return (EXPP_ReturnPyObjError( PyExc_TypeError,
1481                                               "Cannot link to objects.selection or objects.context!" ));        
1482         
1483         /*
1484         if (self->iter != NULL)
1485                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1486                                               "Cannot modify scene objects while iterating" );
1487         */
1488         
1489         if( PyTuple_Size(pyobj) == 1 ) {
1490                 BPy_LibraryData *seq = ( BPy_LibraryData * )PyTuple_GET_ITEM( pyobj, 0 );
1491                 if( BPy_LibraryData_Check( seq ) )
1492                         return LibraryData_importLibData( seq, seq->name,
1493                                         ( seq->kind == OBJECT_IS_LINK ? FILE_LINK : 0 ),
1494                                         self->bpyscene->scene );
1495         }
1496         return Scene_link(self->bpyscene, pyobj);
1497 }
1498
1499 /* This is buggy with new object data not already linked to an object, for now use the above code */
1500 static PyObject *SceneObSeq_new( BPy_SceneObSeq * self, PyObject *args )
1501 {
1502         
1503         void *data = NULL;
1504         char *name = NULL;
1505         char *desc = NULL;
1506         short type = OB_EMPTY;
1507         struct Object *object;
1508         Base *base;
1509         PyObject *py_data;
1510         Scene *scene= self->bpyscene->scene;
1511         
1512         SCENE_DEL_CHECK_PY(self->bpyscene);
1513         
1514         if (self->mode != EXPP_OBSEQ_NORMAL)
1515                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1516                                         "Cannot add new to objects.selection or objects.context!" );    
1517
1518         if( !PyArg_ParseTuple( args, "O|s", &py_data, &name ) )
1519                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1520                                 "scene.objects.new(obdata) - expected obdata to be\n\ta python obdata type or the string 'Empty'" );
1521
1522         if( BPy_Armature_Check( py_data ) ) {
1523                 data = ( void * ) Armature_FromPyObject( py_data );
1524                 type = OB_ARMATURE;
1525         } else if( BPy_Camera_Check( py_data ) ) {
1526                 data = ( void * ) Camera_FromPyObject( py_data );
1527                 type = OB_CAMERA;
1528         } else if( BPy_Lamp_Check( py_data ) ) {
1529                 data = ( void * ) Lamp_FromPyObject( py_data );
1530                 type = OB_LAMP;
1531         } else if( BPy_Curve_Check( py_data ) ) {
1532                 data = ( void * ) Curve_FromPyObject( py_data );
1533                 type = OB_CURVE;
1534         } else if( BPy_NMesh_Check( py_data ) ) {
1535                 data = ( void * ) NMesh_FromPyObject( py_data, NULL );
1536                 type = OB_MESH;
1537                 if( !data )             /* NULL means there is already an error */
1538                         return NULL;
1539         } else if( BPy_Mesh_Check( py_data ) ) {
1540                 data = ( void * ) Mesh_FromPyObject( py_data, NULL );
1541                 type = OB_MESH;
1542         } else if( BPy_Lattice_Check( py_data ) ) {
1543                 data = ( void * ) Lattice_FromPyObject( py_data );
1544                 type = OB_LATTICE;
1545         } else if( BPy_Metaball_Check( py_data ) ) {
1546                 data = ( void * ) Metaball_FromPyObject( py_data );
1547                 type = OB_MBALL;
1548         } else if( BPy_Text3d_Check( py_data ) ) {
1549                 data = ( void * ) Text3d_FromPyObject( py_data );
1550                 type = OB_FONT;
1551         } else if( ( desc = PyString_AsString( (PyObject *)py_data ) ) != NULL ) {
1552                 if( !strcmp( desc, "Empty" ) ) {
1553                         type = OB_EMPTY;
1554                         data = NULL;
1555                 } else
1556                         goto typeError;
1557         } else {
1558 typeError:
1559                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1560                                 "expected an object and optionally a string as arguments" );
1561         }
1562
1563         if (!name) {
1564                 if (type == OB_EMPTY)
1565                         name = "Empty";
1566                 else
1567                         name = ((ID *)data)->name + 2;
1568         }
1569         
1570         object = add_only_object(type, name);
1571         
1572         if( data ) {
1573                 object->data = data;
1574                 id_us_plus((ID *)data);
1575         }
1576         
1577         object->flag = SELECT;
1578         
1579         /* creates the curve for the text object */
1580         if (type == OB_FONT) {
1581                 text_to_curve(object, 0);
1582         } else if (object->type == OB_ARMATURE) {
1583                 armature_rebuild_pose(object, (bArmature *)data);
1584         }
1585         
1586         /* link to scene */
1587         base = MEM_callocN( sizeof( Base ), "pynewbase" );
1588
1589         if( !base )
1590                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1591                                                   "couldn't allocate new Base for object" );
1592
1593         base->object = object;  /* link object to the new base */
1594         
1595         if (scene == G.scene && G.vd) {
1596                 if (G.vd->localview) {
1597                         object->lay= G.vd->layact + G.vd->lay;
1598                 } else {
1599                         object->lay= G.vd->layact;
1600                 }
1601         } else {
1602                 base->lay= object->lay = scene->lay & ((1<<20)-1);      /* Layer, by default visible*/  
1603         }
1604         
1605         base->lay= object->lay;
1606         
1607         base->flag = SELECT;
1608         object->id.us = 1; /* we will exist once in this scene */
1609
1610         BLI_addhead( &(scene->base), base );    /* finally, link new base to scene */
1611         
1612         /* make sure data and object materials are consistent */
1613         test_object_materials( (ID *)object->data );
1614         
1615         /* so we can deal with vertex groups */
1616         if (type == OB_MESH)
1617                 ((BPy_Mesh *)py_data)->object = object;
1618         
1619         return Object_CreatePyObject( object );
1620
1621 }
1622
1623 static PyObject *SceneObSeq_unlink( BPy_SceneObSeq * self, PyObject *args )
1624 {
1625         PyObject *pyobj;
1626         Object *blen_ob;
1627         Scene *scene;
1628         Base *base= NULL;
1629         
1630         SCENE_DEL_CHECK_PY(self->bpyscene);
1631         
1632         if (self->mode != EXPP_OBSEQ_NORMAL)
1633                 return (EXPP_ReturnPyObjError( PyExc_TypeError,
1634                                               "Cannot add new to objects.selection or objects.context!" ));     
1635         
1636         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &pyobj ) )
1637                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1638                                 "expected a python object as an argument" ) );
1639         
1640         blen_ob = ( ( BPy_Object * ) pyobj )->object;
1641         
1642         scene = self->bpyscene->scene;
1643         
1644         /* is the object really in the scene? */
1645         base = object_in_scene( blen_ob, scene);
1646         if( base ) { /* if it is, remove it */
1647                 if (scene->basact==base)
1648                         scene->basact= NULL;    /* in case the object was selected */
1649                 free_and_unlink_base_from_scene(scene, base);
1650                 Py_RETURN_TRUE;
1651         }
1652         Py_RETURN_FALSE;
1653 }
1654
1655 PyObject *SceneObSeq_getActive(BPy_SceneObSeq *self)
1656 {
1657         Base *base;
1658         SCENE_DEL_CHECK_PY(self->bpyscene);
1659         
1660         if (self->mode!=EXPP_OBSEQ_NORMAL)
1661                         return (EXPP_ReturnPyObjError( PyExc_TypeError,
1662                                                 "cannot get active from objects.selected or objects.context" ));
1663         
1664         base= self->bpyscene->scene->basact;
1665         if (!base)
1666                 Py_RETURN_NONE;
1667         
1668         return Object_CreatePyObject( base->object );
1669 }
1670
1671 static int SceneObSeq_setActive(BPy_SceneObSeq *self, PyObject *value)
1672 {
1673         Base *base;
1674         
1675         SCENE_DEL_CHECK_INT(self->bpyscene);
1676         
1677         if (self->mode!=EXPP_OBSEQ_NORMAL)
1678                         return (EXPP_ReturnIntError( PyExc_TypeError,
1679                                                 "cannot set active from objects.selected or objects.context" ));
1680         
1681         if (value==Py_None) {
1682                 self->bpyscene->scene->basact= NULL;
1683                 return 0;
1684         }
1685         
1686         if (!BPy_Object_Check(value))
1687                 return (EXPP_ReturnIntError( PyExc_ValueError,
1688                                               "Object or None types can only be assigned to active!" ));
1689         
1690         base = object_in_scene( ((BPy_Object *)value)->object, self->bpyscene->scene );
1691         
1692         if (!base)
1693                 return (EXPP_ReturnIntError( PyExc_ValueError,
1694                                         "cannot assign an active object outside the scene." ));
1695         
1696         self->bpyscene->scene->basact= base;
1697         return 0;
1698 }
1699
1700 PyObject *SceneObSeq_getCamera(BPy_SceneObSeq *self)
1701 {
1702         SCENE_DEL_CHECK_PY(self->bpyscene);
1703         
1704         if (self->mode!=EXPP_OBSEQ_NORMAL)
1705                         return (EXPP_ReturnPyObjError( PyExc_TypeError,
1706                                                 "cannot get camera from objects.selected or objects.context" ));
1707         
1708         return Object_CreatePyObject( self->bpyscene->scene->camera );
1709 }
1710
1711 static int SceneObSeq_setCamera(BPy_SceneObSeq *self, PyObject *value)
1712 {
1713         int ret;
1714
1715         SCENE_DEL_CHECK_INT(self->bpyscene);
1716         if (self->mode!=EXPP_OBSEQ_NORMAL)
1717                         return EXPP_ReturnIntError( PyExc_TypeError,
1718                                         "cannot set camera from objects.selected or objects.context" );
1719         
1720         ret = GenericLib_assignData(value, (void **) &self->bpyscene->scene->camera, 0, 0, ID_OB, 0);
1721         
1722         /* if this is the current scene, update its window now */
1723         if( ret == 0 && !G.background && self->bpyscene->scene == G.scene ) /* Traced a crash to redrawing while in background mode -Campbell */
1724                 copy_view3d_lock( REDRAW );
1725
1726 /* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
1727  * The same happens in bpython. */
1728
1729         return ret;
1730 }
1731
1732
1733 static struct PyMethodDef BPy_SceneObSeq_methods[] = {
1734         {"link", (PyCFunction)SceneObSeq_link, METH_VARARGS,
1735                 "link object to this scene"},
1736         {"new", (PyCFunction)SceneObSeq_new, METH_VARARGS,
1737                 "Create a new object in this scene from the obdata given and return a new object"},
1738         {"unlink", (PyCFunction)SceneObSeq_unlink, METH_VARARGS,
1739                 "unlinks the object from the scene"},
1740         {NULL, NULL, 0, NULL}
1741 };
1742
1743 /************************************************************************
1744  *
1745  * Python SceneObSeq_Type standard operations
1746  *
1747  ************************************************************************/
1748
1749 static void SceneObSeq_dealloc( BPy_SceneObSeq * self )
1750 {
1751         Py_DECREF(self->bpyscene);
1752         PyObject_DEL( self );
1753 }
1754
1755 static int SceneObSeq_compare( BPy_SceneObSeq * a, BPy_SceneObSeq * b )
1756 {
1757         return ( a->bpyscene->scene == b->bpyscene->scene && a->mode == b->mode) ? 0 : -1;      
1758 }
1759
1760 /*
1761  * repr function
1762  * callback functions building meaninful string to representations
1763  */
1764 static PyObject *SceneObSeq_repr( BPy_SceneObSeq * self )
1765 {
1766         if( !(self->bpyscene->scene) )
1767                 return PyString_FromFormat( "[Scene ObjectSeq Removed]" );
1768         else if (self->mode==EXPP_OBSEQ_SELECTED)
1769                 return PyString_FromFormat( "[Scene ObjectSeq Selected \"%s\"]",
1770                                                 self->bpyscene->scene->id.name + 2 );
1771         else if (self->mode==EXPP_OBSEQ_CONTEXT)
1772                 return PyString_FromFormat( "[Scene ObjectSeq Context \"%s\"]",
1773                                                 self->bpyscene->scene->id.name + 2 );
1774         
1775         /*self->mode==0*/
1776         return PyString_FromFormat( "[Scene ObjectSeq \"%s\"]",
1777                                         self->bpyscene->scene->id.name + 2 );
1778 }
1779
1780 static PyGetSetDef SceneObSeq_getseters[] = {
1781         {"selected",
1782          (getter)SceneObSeq_getObjects, (setter)SceneObSeq_setObjects,
1783          "sequence of selected objects",
1784          (void *)EXPP_OBSEQ_SELECTED},
1785         {"context",
1786          (getter)SceneObSeq_getObjects, (setter)SceneObSeq_setObjects,
1787          "sequence of user context objects",
1788          (void *)EXPP_OBSEQ_CONTEXT},
1789         {"active",
1790          (getter)SceneObSeq_getActive, (setter)SceneObSeq_setActive,
1791          "active object",
1792          NULL},
1793         {"camera",
1794          (getter)SceneObSeq_getCamera, (setter)SceneObSeq_setCamera,
1795          "camera object",
1796          NULL},
1797         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
1798 };
1799
1800 /*****************************************************************************/
1801 /* Python SceneObSeq_Type structure definition:                               */
1802 /*****************************************************************************/
1803 PyTypeObject SceneObSeq_Type = {
1804         PyObject_HEAD_INIT( NULL )  /* required py macro */
1805         0,                          /* ob_size */
1806         /*  For printing, in format "<module>.<name>" */
1807         "Blender SceneObSeq",           /* char *tp_name; */
1808         sizeof( BPy_SceneObSeq ),       /* int tp_basicsize; */
1809         0,                          /* tp_itemsize;  For allocation */
1810
1811         /* Methods to implement standard operations */
1812
1813         ( destructor ) SceneObSeq_dealloc,/* destructor tp_dealloc; */
1814         NULL,                       /* printfunc tp_print; */
1815         NULL,                       /* getattrfunc tp_getattr; */
1816         NULL,                       /* setattrfunc tp_setattr; */
1817         ( cmpfunc ) SceneObSeq_compare, /* cmpfunc tp_compare; */
1818         ( reprfunc ) SceneObSeq_repr,   /* reprfunc tp_repr; */
1819
1820         /* Method suites for standard classes */
1821
1822         NULL,                       /* PyNumberMethods *tp_as_number; */
1823         &SceneObSeq_as_sequence,            /* PySequenceMethods *tp_as_sequence; */
1824         NULL,                       /* PyMappingMethods *tp_as_mapping; */
1825
1826         /* More standard operations (here for binary compatibility) */
1827
1828         NULL,                       /* hashfunc tp_hash; */
1829         NULL,                       /* ternaryfunc tp_call; */
1830         NULL,                       /* reprfunc tp_str; */
1831         NULL,                       /* getattrofunc tp_getattro; */
1832         NULL,                       /* setattrofunc tp_setattro; */
1833
1834         /* Functions to access object as input/output buffer */
1835         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1836
1837   /*** Flags to define presence of optional/expanded features ***/
1838         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
1839
1840         NULL,                       /*  char *tp_doc;  Documentation string */
1841   /*** Assigned meaning in release 2.0 ***/
1842         /* call function for all accessible objects */
1843         NULL,                       /* traverseproc tp_traverse; */
1844
1845         /* delete references to contained objects */
1846         NULL,                       /* inquiry tp_clear; */
1847
1848   /***  Assigned meaning in release 2.1 ***/
1849   /*** rich comparisons ***/
1850         NULL,                       /* richcmpfunc tp_richcompare; */
1851
1852   /***  weak reference enabler ***/
1853         0,                          /* long tp_weaklistoffset; */
1854
1855   /*** Added in release 2.2 ***/
1856         /*   Iterators */
1857         ( getiterfunc) SceneObSeq_getIter, /* getiterfunc tp_iter; */
1858         ( iternextfunc ) SceneObSeq_nextIter, /* iternextfunc tp_iternext; */
1859
1860   /*** Attribute descriptor and subclassing stuff ***/
1861         BPy_SceneObSeq_methods,       /* struct PyMethodDef *tp_methods; */
1862         NULL,                       /* struct PyMemberDef *tp_members; */
1863         SceneObSeq_getseters,       /* struct PyGetSetDef *tp_getset; */
1864         NULL,                       /* struct _typeobject *tp_base; */
1865         NULL,                       /* PyObject *tp_dict; */
1866         NULL,                       /* descrgetfunc tp_descr_get; */
1867         NULL,                       /* descrsetfunc tp_descr_set; */
1868         0,                          /* long tp_dictoffset; */
1869         NULL,                       /* initproc tp_init; */
1870         NULL,                       /* allocfunc tp_alloc; */
1871         NULL,                       /* newfunc tp_new; */
1872         /*  Low-level free-memory routine */
1873         NULL,                       /* freefunc tp_free;  */
1874         /* For PyObject_IS_GC */
1875         NULL,                       /* inquiry tp_is_gc;  */
1876         NULL,                       /* PyObject *tp_bases; */
1877         /* method resolution order */
1878         NULL,                       /* PyObject *tp_mro;  */
1879         NULL,                       /* PyObject *tp_cache; */
1880         NULL,                       /* PyObject *tp_subclasses; */
1881         NULL,                       /* PyObject *tp_weaklist; */
1882         NULL
1883 };