resolve some compiler warnings with intel c/c++ compiler
[blender-staging.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 static 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 *name = NULL;
639         Scene *scene_iter;
640
641         if( !PyArg_ParseTuple( args, "|s", &name ) )
642                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
643                                                 "expected string argument (or nothing)" ) );
644         
645         scene_iter = G.main->scene.first;
646
647         if( name ) {            /* (name) - Search scene by name */
648
649                 PyObject *wanted_scene = NULL;
650
651                 for(;scene_iter; scene_iter = scene_iter->id.next) {
652                         if( strcmp( name, scene_iter->id.name + 2 ) == 0 ) {
653                                 wanted_scene = Scene_CreatePyObject( scene_iter );
654                                 break;
655                         }
656                 }
657
658                 if( wanted_scene == NULL ) {    /* Requested scene doesn't exist */
659                         char error_msg[64];
660                         PyOS_snprintf( error_msg, sizeof( error_msg ),
661                                        "Scene \"%s\" not found", name );
662                         return ( EXPP_ReturnPyObjError
663                                  ( PyExc_NameError, error_msg ) );
664                 }
665
666                 return wanted_scene;
667         }
668
669         else {  /* () - return a list with wrappers for all scenes in Blender */
670                 int index = 0;
671                 PyObject *sce_pylist, *pyobj;
672
673                 sce_pylist = PyList_New( BLI_countlist( &( G.main->scene ) ) );
674
675                 if( sce_pylist == NULL )
676                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
677                                                         "couldn't create PyList" ) );
678
679                 for(; scene_iter; scene_iter = scene_iter->id.next, index++) {
680                         pyobj = Scene_CreatePyObject( scene_iter );
681
682                         if( !pyobj ) {
683                                 Py_DECREF(sce_pylist);
684                                 return NULL; /* Scene_CreatePyObject sets an error */
685                         }
686                         PyList_SET_ITEM( sce_pylist, index, pyobj );
687                 }
688
689                 return sce_pylist;
690         }
691 }
692
693 /*-----------------------Scene.GetCurrent()------------------------------*/
694 static PyObject *M_Scene_GetCurrent( PyObject * self )
695 {
696         return Scene_CreatePyObject( ( Scene * ) G.scene );
697 }
698
699 static PyObject *M_Scene_getCurrent_deprecated( PyObject * self )
700 {
701         static char warning = 1;
702         if( warning ) {
703                 printf("Blender.Scene.getCurrent() is deprecated,\n\tuse Blender.Scene.GetCurrent() instead.\n");
704                 --warning;
705         }
706
707         return Scene_CreatePyObject( ( Scene * ) G.scene );
708 }
709
710
711 /*-----------------------Scene.Unlink()----------------------------------*/
712 static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
713 {
714         PyObject *pyobj;
715         BPy_Scene *pyscn;
716         Scene *scene, *sce;
717         bScreen *sc;
718         
719         if( !PyArg_ParseTuple( args, "O!", &Scene_Type, &pyobj ) )
720                 return EXPP_ReturnPyObjError( PyExc_TypeError,
721                                               "expected Scene PyType object" );
722         
723         pyscn = (BPy_Scene *)pyobj;
724         scene = pyscn->scene;
725         
726         SCENE_DEL_CHECK_PY(pyscn);
727         
728         if( scene == G.scene )
729                 return EXPP_ReturnPyObjError( PyExc_SystemError,
730                                               "current Scene cannot be removed!" );
731
732         /* Copied from header_info.c */
733         
734         /* check all sets */
735         for (sce= G.main->scene.first; sce; sce= sce->id.next) {
736                 if(sce->set == scene) sce->set= 0;
737         }
738         
739         /* check all sequences */
740         clear_scene_in_allseqs(scene);
741
742         /* check render layer nodes in other scenes */
743         clear_scene_in_nodes(scene);
744         
745         for (sc= G.main->screen.first; sc; sc= sc->id.next ) {
746                 if(sc->scene == scene) sc->scene= G.scene;
747         }
748         
749         free_libblock( &G.main->scene, scene );
750         
751         pyscn->scene= NULL;
752         Py_RETURN_NONE;
753 }
754
755 /* DEPRECATE ME !!! */
756 /*-----------------------BPy_Scene function defintions-------------------*/
757
758 /*-----------------------Scene.setLayers()---------------------------------*/
759 static PyObject *Scene_oldsetLayers( BPy_Scene * self, PyObject * args )
760 {
761         return EXPP_setterWrapper( (void *)self, args, (setter)Scene_setLayerList );
762 }
763 /* END DEPRECATE CODE */
764
765
766 /*-----------------------Scene.copy()------------------------------------*/
767 static PyObject *Scene_copy( BPy_Scene * self, PyObject * args )
768 {
769         short dup_objs = 2;
770         Scene *scene = self->scene;
771
772         SCENE_DEL_CHECK_PY(self);
773
774         if( !PyArg_ParseTuple( args, "|h", &dup_objs ) || dup_objs < 0 || dup_objs > 2)
775                 return EXPP_ReturnPyObjError( PyExc_TypeError,
776                                               "expected int in [0,2] or nothing as argument" );
777         
778         return Scene_CreatePyObject( copy_scene( scene, dup_objs+1 ) );
779 }
780
781 /*-----------------------Scene.makeCurrent()-----------------------------*/
782 static PyObject *Scene_makeCurrent( BPy_Scene * self )
783 {
784         Scene *scene = self->scene;
785 #if 0   /* add back in when bpy becomes "official" */
786         static char warning = 1;
787         if( warning ) {
788                 printf("scene.makeCurrent() deprecated!\n\tuse bpy.scenes.active = scene instead\n");
789                 --warning;
790         }
791 #endif
792
793         SCENE_DEL_CHECK_PY(self);
794         
795         if( scene && scene != G.scene) {
796                 set_scene( scene );
797                 scene_update_for_newframe(scene, scene->lay);
798         }
799
800         Py_RETURN_NONE;
801 }
802
803 /*-----------------------Scene.update()----------------------------------*/
804 static PyObject *Scene_update( BPy_Scene * self, PyObject * args )
805 {
806         Scene *scene = self->scene;
807         int full = 0;
808         
809         SCENE_DEL_CHECK_PY(self);
810         if( !PyArg_ParseTuple( args, "|i", &full ) )
811                 return EXPP_ReturnPyObjError( PyExc_TypeError,
812                                               "expected nothing or int (0 or 1) argument" );
813
814 /* Under certain circunstances, DAG_scene_sort *here* can crash Blender.
815  * A "RuntimeError: max recursion limit" happens when a scriptlink
816  * on frame change has scene.update(1).
817  * Investigate better how to avoid this. */
818         if( !full )
819                 DAG_scene_sort( scene );
820
821         else if( full == 1 ) {
822                 int enablescripts = G.f & G_DOSCRIPTLINKS;
823                 
824                 /*Disable scriptlinks to prevent firing off newframe scriptlink
825                   events.*/
826                 G.f &= ~G_DOSCRIPTLINKS;
827                 set_scene_bg( scene );
828                 scene_update_for_newframe( scene, scene->lay );
829                 
830                 /*re-enabled scriptlinks if necassary.*/
831                 if (enablescripts) G.f |= G_DOSCRIPTLINKS;
832         } else
833                 return EXPP_ReturnPyObjError( PyExc_ValueError,
834                                               "in method scene.update(full), full should be:\n"
835                                               "0: to only sort scene elements (old behavior); or\n"
836                                               "1: for a full update (regroups, does ipos, keys, etc.)" );
837
838         Py_RETURN_NONE;
839 }
840
841 /*-----------------------Scene.link()------------------------------------*/
842 static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
843 {
844         Scene *scene = self->scene;
845         BPy_Object *bpy_obj;
846         Object *object = NULL;
847         static char warning = 1;
848
849         if( warning ) {
850                 printf("scene.link(ob) deprecated!\n\tuse scene.objects.link(ob) instead\n");
851                 --warning;
852         }
853
854         SCENE_DEL_CHECK_PY(self);
855         
856         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
857                 return EXPP_ReturnPyObjError( PyExc_TypeError,
858                                               "expected Object argument" );
859         
860         
861                 /*return EXPP_ReturnPyObjError( PyExc_RuntimeError,
862                                                   "Could not create data on demand for this object type!" );*/
863         
864         object = bpy_obj->object;
865         
866         /* Object.c's EXPP_add_obdata does not support these objects */
867         if (!object->data && (object->type == OB_SURF || object->type == OB_FONT || object->type == OB_WAVE )) {
868                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
869                                               "Object has no data and new data cant be automaticaly created for Surf, Text or Wave type objects!" );
870         } else {
871                 /* Ok, all is fine, let's try to link it */
872                 Base *base;
873
874                 /* We need to link the object to a 'Base', then link this base
875                  * to the scene.        See DNA_scene_types.h ... */
876
877                 /* First, check if the object isn't already in the scene */
878                 base = object_in_scene( object, scene );
879                 /* if base is not NULL ... */
880                 if( base )      /* ... the object is already in one of the Scene Bases */
881                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
882                                                       "object already in scene!" );
883
884                 /* not linked, go get mem for a new base object */
885
886                 base = MEM_callocN( sizeof( Base ), "pynewbase" );
887
888                 if( !base )
889                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
890                                                       "couldn't allocate new Base for object" );
891
892                 /*  if the object has not yet been linked to object data, then
893                  *  set the real type before we try creating data */
894
895                 if( bpy_obj->realtype != OB_EMPTY ) {
896                         object->type = bpy_obj->realtype;
897                         bpy_obj->realtype = OB_EMPTY;
898                 }
899
900                 /* check if this object has obdata, case not, try to create it */
901
902                 if( !object->data && ( object->type != OB_EMPTY ) )
903                         EXPP_add_obdata( object ); /* returns -1 on error, defined in Object.c */
904
905                 base->object = object;  /* link object to the new base */
906                 base->lay = object->lay;
907                 base->flag = object->flag;
908
909                 object->id.us += 1;     /* incref the object user count in Blender */
910
911                 BLI_addhead( &scene->base, base );      /* finally, link new base to scene */
912         }
913
914         Py_RETURN_NONE;
915 }
916
917 /*-----------------------Scene.unlink()----------------------------------*/
918 static PyObject *Scene_unlink( BPy_Scene * self, PyObject * args )
919 {
920         BPy_Object *bpy_obj = NULL;
921         Scene *scene = self->scene;
922         Base *base;
923         static char warning = 1;
924
925         if( warning ) {
926                 printf("scene.unlink(ob) deprecated!\n\tuse scene.objects.unlink(ob) instead\n");
927                 --warning;
928         }
929
930         SCENE_DEL_CHECK_PY(self);
931         
932         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
933                 return EXPP_ReturnPyObjError( PyExc_TypeError,
934                                               "expected Object as argument" );
935
936         /* is the object really in the scene? */
937         base = object_in_scene( bpy_obj->object, scene );
938
939         if( base ) {            /* if it is, remove it */
940                 if (scene->basact==base)
941                         scene->basact= NULL;    /* in case the object was selected */
942                 
943                 free_and_unlink_base_from_scene( scene, base );
944                 Py_RETURN_TRUE;
945         }
946         else
947                 Py_RETURN_FALSE;
948 }
949
950 /*-----------------------Scene.getChildren()-----------------------------*/
951 static PyObject *Scene_getChildren( BPy_Scene * self )
952 {
953         Scene *scene = self->scene;
954         PyObject *pylist;
955         PyObject *bpy_obj;
956         Object *object;
957         Base *base;
958         static char warning = 1;
959
960         if( warning ) {
961                 printf("scene.getChildren() deprecated!\n\tuse scene.objects instead\n");
962                 --warning;
963         }
964
965         SCENE_DEL_CHECK_PY(self);
966
967         pylist = PyList_New( 0 );
968         
969         base = scene->base.first;
970
971         while( base ) {
972                 object = base->object;
973                 
974                 bpy_obj = Object_CreatePyObject( object );
975                 
976                 if( !bpy_obj ) {
977                         Py_DECREF(pylist);
978                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
979                                                       "couldn't create new object wrapper" );
980                 }
981                 PyList_Append( pylist, bpy_obj );
982                 Py_DECREF( bpy_obj );   /* PyList_Append incref'ed it */
983                 
984                 base = base->next;
985         }
986
987         return pylist;
988 }
989
990 /*-----------------------Scene.getActiveObject()------------------------*/
991 static PyObject *Scene_getActiveObject(BPy_Scene *self)
992 {
993         Scene *scene = self->scene;
994         PyObject *pyob;
995         Object *ob;
996         static char warning = 1;
997
998         if( warning ) {
999                 printf("scene.getActiveObject() deprecated!\n\tuse scene.objects.active instead\n");
1000                 --warning;
1001         }
1002
1003         SCENE_DEL_CHECK_PY(self);
1004         
1005         ob = ((scene->basact) ? (scene->basact->object) : 0);
1006
1007         if (ob) {
1008                 pyob = Object_CreatePyObject( ob );
1009
1010                 if (!pyob)
1011                         return EXPP_ReturnPyObjError(PyExc_MemoryError,
1012                                         "couldn't create new object wrapper!");
1013
1014                 return pyob;
1015         }
1016
1017         Py_RETURN_NONE; /* no active object */
1018 }
1019
1020 /*-----------------------Scene.getCurrentCamera()------------------------*/
1021 static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
1022 {
1023         static char warning = 1;
1024         
1025         if( warning ) {
1026                 printf("scene.getCurrentCamera() deprecated!\n\tuse scene.objects.camera instead\n");
1027                 --warning;
1028         }
1029
1030         SCENE_DEL_CHECK_PY(self);
1031         /* None is ok */
1032         return Object_CreatePyObject( self->scene->camera );
1033 }
1034
1035 /*-----------------------Scene.setCurrentCamera()------------------------*/
1036 static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args )
1037 {
1038         Object *object;
1039         BPy_Object *cam_obj;
1040         Scene *scene = self->scene;
1041         static char warning = 1;
1042
1043         if( warning ) {
1044                 printf("scene.setCurrentCamera(ob) deprecated!\n\tSet scene.objects.camera = ob instead\n");
1045                 --warning;
1046         }
1047
1048         SCENE_DEL_CHECK_PY(self);
1049         
1050         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &cam_obj ) )
1051                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1052                                               "expected Camera Object as argument" );
1053
1054         object = cam_obj->object;
1055         if( object->type != OB_CAMERA )
1056                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1057                                               "expected Camera Object as argument" );
1058
1059         scene->camera = object; /* set the current Camera */
1060
1061         /* if this is the current scene, update its window now */
1062         if( !G.background && scene == G.scene ) /* Traced a crash to redrawing while in background mode -Campbell */
1063                 copy_view3d_lock( REDRAW );
1064
1065 /* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
1066  * The same happens in bpython. */
1067
1068         Py_RETURN_NONE;
1069 }
1070
1071 /*-----------------------Scene.getRenderingContext()---------------------*/
1072 static PyObject *Scene_getRenderingContext( BPy_Scene * self )
1073 {
1074         SCENE_DEL_CHECK_PY(self);
1075         return RenderData_CreatePyObject( self->scene );
1076 }
1077
1078 static PyObject *Scene_getRadiosityContext( BPy_Scene * self )
1079 {
1080         SCENE_DEL_CHECK_PY(self);
1081         return Radio_CreatePyObject( self->scene );
1082 }
1083
1084 static PyObject *Scene_getSequence( BPy_Scene * self )
1085 {
1086         SCENE_DEL_CHECK_PY(self);
1087         return SceneSeq_CreatePyObject( self->scene, NULL );
1088 }
1089
1090 /* scene.addScriptLink */
1091 static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args )
1092 {
1093         Scene *scene = self->scene;
1094         ScriptLink *slink = NULL;
1095
1096         SCENE_DEL_CHECK_PY(self);
1097
1098         slink = &( scene )->scriptlink;
1099
1100         return EXPP_addScriptLink( slink, args, 1 );
1101 }
1102
1103 /* scene.clearScriptLinks */
1104 static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args )
1105 {
1106         Scene *scene = self->scene;
1107         ScriptLink *slink = NULL;
1108
1109         SCENE_DEL_CHECK_PY(self);
1110
1111         slink = &( scene )->scriptlink;
1112
1113         return EXPP_clearScriptLinks( slink, args );
1114 }
1115
1116 /* scene.getScriptLinks */
1117 static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * value )
1118 {
1119         Scene *scene = self->scene;
1120         ScriptLink *slink = NULL;
1121         PyObject *ret = NULL;
1122
1123         SCENE_DEL_CHECK_PY(self);
1124
1125         slink = &( scene )->scriptlink;
1126
1127         ret = EXPP_getScriptLinks( slink, value, 1 );
1128
1129         if( ret )
1130                 return ret;
1131         else
1132                 return NULL;
1133 }
1134
1135 static PyObject *Scene_play( BPy_Scene * self, PyObject * args )
1136 {
1137         int mode = 0, win = SPACE_VIEW3D;
1138         PyObject *ret = NULL;
1139         ScrArea *sa = NULL, *oldsa = curarea;
1140
1141         SCENE_DEL_CHECK_PY(self);
1142
1143         if( !PyArg_ParseTuple( args, "|ii", &mode, &win ) )
1144                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1145                                               "expected nothing, or or two ints as arguments." );
1146
1147         if( mode < 0 || mode > 3 )
1148                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1149                                               "mode should be in range [0, 3]." );
1150
1151         switch ( win ) {
1152         case SPACE_VIEW3D:
1153         case SPACE_SEQ:
1154         case SPACE_IPO:
1155         case SPACE_ACTION:
1156         case SPACE_NLA:
1157         case SPACE_SOUND:
1158         case SPACE_BUTS:        /* from here they don't 'play', but ... */
1159         case SPACE_TEXT:        /* ... might be used as a timer. */
1160         case SPACE_SCRIPT:
1161         case SPACE_OOPS:
1162         case SPACE_IMAGE:
1163         case SPACE_IMASEL:
1164         case SPACE_INFO:
1165         case SPACE_FILE:
1166                 break;
1167         default:
1168                 win = SPACE_VIEW3D;
1169         }
1170
1171         /* we have to move to a proper win */
1172         sa = find_biggest_area_of_type( win );
1173         if( !sa && win != SPACE_VIEW3D )
1174                 sa = find_biggest_area_of_type( SPACE_VIEW3D );
1175
1176         if( !sa )
1177                 sa = find_biggest_area(  );
1178
1179         if( sa )
1180                 areawinset( sa->win );
1181
1182         /* play_anim returns 0 for normal exit or 1 if user canceled it */
1183         ret = PyInt_FromLong( (long)play_anim( mode ) );
1184
1185         if( sa )
1186                 areawinset( oldsa->win );
1187
1188         return ret;
1189 }
1190
1191 static PyObject *Scene_getTimeLine( BPy_Scene *self ) 
1192 {
1193         BPy_TimeLine *tm; 
1194
1195         SCENE_DEL_CHECK_PY(self);
1196         
1197         tm= (BPy_TimeLine *) PyObject_NEW (BPy_TimeLine, &TimeLine_Type);
1198         if (!tm)
1199                 return EXPP_ReturnPyObjError (PyExc_MemoryError,
1200                                               "couldn't create BPy_TimeLine object");
1201         tm->marker_list= &(self->scene->markers);
1202         tm->sfra= (int) self->scene->r.sfra;
1203         tm->efra= (int) self->scene->r.efra;
1204
1205         return (PyObject *)tm;
1206 }
1207
1208 /************************************************************************
1209  *
1210  * Object Sequence 
1211  *
1212  ************************************************************************/
1213 /*
1214  * create a thin wrapper for the scenes objects
1215  */
1216
1217 /* accessed from scn.objects.selected or scn.objects.context */
1218 static PyObject *SceneObSeq_getObjects( BPy_SceneObSeq *self, void *mode) 
1219 {
1220         SCENE_DEL_CHECK_PY(self->bpyscene);
1221         return SceneObSeq_CreatePyObject(self->bpyscene, NULL, (int)((long)mode));
1222 }
1223
1224 static int SceneObSeq_setObjects( BPy_SceneObSeq *self, PyObject *value, void *_mode_) 
1225 {
1226         /*
1227         ONLY SUPPORTS scn.objects.selected and scn.objects.context 
1228         cannot assign to scn.objects yet!!!
1229         */
1230         PyObject *item;
1231         Scene *scene= self->bpyscene->scene;
1232         Object *blen_ob;
1233         Base *base;
1234         int size, mode = GET_INT_FROM_POINTER(_mode_);
1235         
1236         SCENE_DEL_CHECK_INT(self->bpyscene);
1237         
1238         /* scn.objects.selected = scn.objects  - shortcut to select all */
1239         if (BPy_SceneObSeq_Check(value)) {
1240                 BPy_SceneObSeq *bpy_sceneseq = (BPy_SceneObSeq *)value;
1241                 if (self->bpyscene->scene != bpy_sceneseq->bpyscene->scene)
1242                         return EXPP_ReturnIntError( PyExc_ValueError,
1243                                         "Cannot assign a SceneObSeq type from another scene" );
1244                 if (bpy_sceneseq->mode != EXPP_OBSEQ_NORMAL)
1245                         return EXPP_ReturnIntError( PyExc_ValueError,
1246                                         "Can only assign scn.objects to scn.objects.context or scn.objects.selected" );
1247                 
1248                 for (base= scene->base.first; base; base= base->next) {
1249                         base->flag |= SELECT;
1250                         base->object->flag |= SELECT;
1251                         
1252                         if (mode==EXPP_OBSEQ_CONTEXT && G.vd) {
1253                                 base->object->lay= base->lay= G.vd->lay;
1254                         }
1255                 }
1256                 return 0;
1257         }
1258
1259         if (!PySequence_Check(value))
1260                 return EXPP_ReturnIntError( PyExc_ValueError,
1261                                 "Error, must assign a sequence of objects to scn.objects.selected" );
1262         
1263         /* for context and selected, just deselect, dont remove */
1264         for (base= scene->base.first; base; base= base->next) {
1265                 base->flag &= ~SELECT;
1266                 base->object->flag &= ~SELECT;
1267         }
1268         
1269         size = PySequence_Length(value);
1270         while (size) {
1271                 size--;
1272                 item = PySequence_GetItem(value, size);
1273                 if ( PyObject_TypeCheck(item, &Object_Type) ) {
1274                         blen_ob= ((BPy_Object *)item)->object;
1275                         base = object_in_scene( blen_ob, scene );
1276                         if (base) {
1277                                 blen_ob->flag |= SELECT;
1278                                 base->flag |= SELECT;
1279                                 if (mode==EXPP_OBSEQ_CONTEXT && G.vd) {
1280                                         blen_ob->restrictflag &= ~OB_RESTRICT_VIEW;
1281                                         blen_ob->lay= base->lay= G.vd->lay;
1282                                 }
1283                         }
1284                 }
1285                 Py_DECREF(item);
1286         }
1287         return 0;
1288 }
1289
1290
1291 static PyObject *SceneObSeq_CreatePyObject( BPy_Scene *self, Base *iter, int mode )
1292 {
1293         BPy_SceneObSeq *seq = PyObject_NEW( BPy_SceneObSeq, &SceneObSeq_Type);
1294         seq->bpyscene = self; Py_INCREF(self);
1295         seq->iter = iter;
1296         seq->mode = mode;
1297         return (PyObject *)seq;
1298 }
1299
1300 static int SceneObSeq_len( BPy_SceneObSeq * self )
1301 {
1302         Scene *scene= self->bpyscene->scene;
1303         SCENE_DEL_CHECK_INT(self->bpyscene);
1304         
1305         if (self->mode == EXPP_OBSEQ_NORMAL)
1306                 return BLI_countlist( &( scene->base ) );
1307         else if (self->mode == EXPP_OBSEQ_SELECTED) {
1308                 int len=0;
1309                 Base *base;
1310                 for (base= scene->base.first; base; base= base->next) {
1311                         if (base->flag & SELECT) {
1312                                 len++;
1313                         }
1314                 }
1315                 return len;
1316         } else if (self->mode == EXPP_OBSEQ_CONTEXT) {
1317                 int len=0;
1318                 Base *base;
1319                 
1320                 if( G.vd == NULL ) /* No 3d view has been initialized yet, simply return an empty list */
1321                         return 0;
1322                 
1323                 for (base= scene->base.first; base; base= base->next) {
1324                         if TESTBASE(base) {
1325                                 len++;
1326                         }
1327                 }
1328                 return len;
1329         }
1330         /*should never run this */
1331         return 0;
1332 }
1333
1334 /*
1335  * retrive a single Object from somewhere in the Object list
1336  */
1337
1338 static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i )
1339 {
1340         int index=0;
1341         Base *base= NULL;
1342         Scene *scene= self->bpyscene->scene;
1343         
1344         SCENE_DEL_CHECK_PY(self->bpyscene);
1345         
1346         /* objects */
1347         if (self->mode==EXPP_OBSEQ_NORMAL)
1348                 for (base= scene->base.first; base && i!=index; base= base->next, index++) {}
1349         /* selected */
1350         else if (self->mode==EXPP_OBSEQ_SELECTED) {
1351                 for (base= scene->base.first; base; base= base->next) {
1352                         if (base->flag & SELECT) {
1353                                 if (i==index) {
1354                                         break;
1355                                 } else {
1356                                         index++;
1357                                 }
1358                         }
1359                 }
1360         }
1361         /* context */
1362         else if (self->mode==EXPP_OBSEQ_CONTEXT) {
1363                 if (G.vd) {
1364                         for (base= scene->base.first; base; base= base->next) {
1365                                 if (TESTBASE(base)) {
1366                                         if (i==index) {
1367                                                 break;
1368                                         } else {
1369                                                 index++;
1370                                         }
1371                                 }
1372                         }
1373                 }
1374         }
1375         
1376         if (!(base))
1377                 return EXPP_ReturnPyObjError( PyExc_IndexError,
1378                                               "array index out of range" );
1379         
1380         return Object_CreatePyObject( base->object );
1381 }
1382
1383 static PySequenceMethods SceneObSeq_as_sequence = {
1384         ( inquiry ) SceneObSeq_len,     /* sq_length */
1385         ( binaryfunc ) 0,       /* sq_concat */
1386         ( intargfunc ) 0,       /* sq_repeat */
1387         ( intargfunc ) SceneObSeq_item, /* sq_item */
1388         ( intintargfunc ) 0,    /* sq_slice */
1389         ( intobjargproc ) 0,    /* sq_ass_item */
1390         ( intintobjargproc ) 0, /* sq_ass_slice */
1391         0,0,0,
1392 };
1393
1394
1395 /************************************************************************
1396  *
1397  * Python SceneObSeq_Type iterator (iterates over GroupObjects)
1398  *
1399  ************************************************************************/
1400
1401 /*
1402  * Initialize the interator index
1403  */
1404
1405 static PyObject *SceneObSeq_getIter( BPy_SceneObSeq * self )
1406 {
1407         /* we need to get the first base, but for selected context we may need to advance
1408         to the first selected or first conext base */
1409         Base *base= self->bpyscene->scene->base.first;
1410         
1411         SCENE_DEL_CHECK_PY(self->bpyscene);
1412         
1413         if (self->mode==EXPP_OBSEQ_SELECTED)
1414                 while (base && !(base->flag & SELECT))
1415                         base= base->next;
1416         else if (self->mode==EXPP_OBSEQ_CONTEXT) {
1417                 if (!G.vd)
1418                         base= NULL; /* will never iterate if we have no */
1419                 else
1420                         while (base && !TESTBASE(base))
1421                                 base= base->next;       
1422         }
1423         /* create a new iterator if were alredy using this one */
1424         if (self->iter==NULL) {
1425                 self->iter = base;
1426                 return EXPP_incr_ret ( (PyObject *) self );
1427         } else {
1428                 return SceneObSeq_CreatePyObject(self->bpyscene, base, self->mode);
1429         }
1430 }
1431
1432 /*
1433  * Return next SceneOb.
1434  */
1435
1436 static PyObject *SceneObSeq_nextIter( BPy_SceneObSeq * self )
1437 {
1438         PyObject *object;
1439         Base *base;
1440         if( !(self->iter) ||  !(self->bpyscene->scene) ) {
1441                 self->iter= NULL;
1442                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
1443                                 "iterator at end" );
1444         }
1445         
1446         object= Object_CreatePyObject( self->iter->object ); 
1447         base= self->iter->next;
1448         
1449         if (self->mode==EXPP_OBSEQ_SELECTED)
1450                 while (base && !(base->flag & SELECT))
1451                         base= base->next;
1452         else if (self->mode==EXPP_OBSEQ_CONTEXT) {
1453                 if (!G.vd)
1454                         base= NULL; /* will never iterate if we have no */
1455                 else
1456                         while (base && !TESTBASE(base))
1457                                 base= base->next;       
1458         }
1459         self->iter= base;
1460         return object;
1461 }
1462
1463
1464 static PyObject *SceneObSeq_link( BPy_SceneObSeq * self, PyObject *pyobj )
1465 {       
1466         SCENE_DEL_CHECK_PY(self->bpyscene);
1467         
1468         /* this shold eventually replace Scene_link */
1469         if (self->mode != EXPP_OBSEQ_NORMAL)
1470                 return (EXPP_ReturnPyObjError( PyExc_TypeError,
1471                                               "Cannot link to objects.selection or objects.context!" ));        
1472         
1473         /*
1474         if (self->iter != NULL)
1475                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1476                                               "Cannot modify scene objects while iterating" );
1477         */
1478         
1479         if( PyTuple_Size(pyobj) == 1 ) {
1480                 BPy_LibraryData *seq = ( BPy_LibraryData * )PyTuple_GET_ITEM( pyobj, 0 );
1481                 if( BPy_LibraryData_Check( seq ) )
1482                         return LibraryData_importLibData( seq, seq->name,
1483                                         ( seq->kind == OBJECT_IS_LINK ? FILE_LINK : 0 ),
1484                                         self->bpyscene->scene );
1485         }
1486         return Scene_link(self->bpyscene, pyobj);
1487 }
1488
1489 /* This is buggy with new object data not already linked to an object, for now use the above code */
1490 static PyObject *SceneObSeq_new( BPy_SceneObSeq * self, PyObject *args )
1491 {
1492         
1493         void *data = NULL;
1494         char *name = NULL;
1495         char *desc = NULL;
1496         short type = OB_EMPTY;
1497         struct Object *object;
1498         Base *base;
1499         PyObject *py_data;
1500         Scene *scene= self->bpyscene->scene;
1501         
1502         SCENE_DEL_CHECK_PY(self->bpyscene);
1503         
1504         if (self->mode != EXPP_OBSEQ_NORMAL)
1505                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1506                                         "Cannot add new to objects.selection or objects.context!" );    
1507
1508         if( !PyArg_ParseTuple( args, "O|s", &py_data, &name ) )
1509                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1510                                 "scene.objects.new(obdata) - expected obdata to be\n\ta python obdata type or the string 'Empty'" );
1511
1512         if( BPy_Armature_Check( py_data ) ) {
1513                 data = ( void * ) Armature_FromPyObject( py_data );
1514                 type = OB_ARMATURE;
1515         } else if( BPy_Camera_Check( py_data ) ) {
1516                 data = ( void * ) Camera_FromPyObject( py_data );
1517                 type = OB_CAMERA;
1518         } else if( BPy_Lamp_Check( py_data ) ) {
1519                 data = ( void * ) Lamp_FromPyObject( py_data );
1520                 type = OB_LAMP;
1521         } else if( BPy_Curve_Check( py_data ) ) {
1522                 data = ( void * ) Curve_FromPyObject( py_data );
1523                 type = OB_CURVE;
1524         } else if( BPy_NMesh_Check( py_data ) ) {
1525                 data = ( void * ) NMesh_FromPyObject( py_data, NULL );
1526                 type = OB_MESH;
1527                 if( !data )             /* NULL means there is already an error */
1528                         return NULL;
1529         } else if( BPy_Mesh_Check( py_data ) ) {
1530                 data = ( void * ) Mesh_FromPyObject( py_data, NULL );
1531                 type = OB_MESH;
1532         } else if( BPy_Lattice_Check( py_data ) ) {
1533                 data = ( void * ) Lattice_FromPyObject( py_data );
1534                 type = OB_LATTICE;
1535         } else if( BPy_Metaball_Check( py_data ) ) {
1536                 data = ( void * ) Metaball_FromPyObject( py_data );
1537                 type = OB_MBALL;
1538         } else if( BPy_Text3d_Check( py_data ) ) {
1539                 data = ( void * ) Text3d_FromPyObject( py_data );
1540                 type = OB_FONT;
1541         } else if( ( desc = PyString_AsString( (PyObject *)py_data ) ) != NULL ) {
1542                 if( !strcmp( desc, "Empty" ) ) {
1543                         type = OB_EMPTY;
1544                         data = NULL;
1545                 } else
1546                         goto typeError;
1547         } else {
1548 typeError:
1549                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1550                                 "expected an object and optionally a string as arguments" );
1551         }
1552
1553         if (!name) {
1554                 if (type == OB_EMPTY)
1555                         name = "Empty";
1556                 else
1557                         name = ((ID *)data)->name + 2;
1558         }
1559         
1560         object = add_only_object(type, name);
1561         
1562         if( data ) {
1563                 object->data = data;
1564                 id_us_plus((ID *)data);
1565         }
1566         
1567         object->flag = SELECT;
1568         
1569         /* creates the curve for the text object */
1570         if (type == OB_FONT) {
1571                 text_to_curve(object, 0);
1572         } else if (object->type == OB_ARMATURE) {
1573                 armature_rebuild_pose(object, (bArmature *)data);
1574         }
1575         
1576         /* link to scene */
1577         base = MEM_callocN( sizeof( Base ), "pynewbase" );
1578
1579         if( !base )
1580                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1581                                                   "couldn't allocate new Base for object" );
1582
1583         base->object = object;  /* link object to the new base */
1584         
1585         if (scene == G.scene && G.vd) {
1586                 if (G.vd->localview) {
1587                         object->lay= G.vd->layact + G.vd->lay;
1588                 } else {
1589                         object->lay= G.vd->layact;
1590                 }
1591         } else {
1592                 base->lay= object->lay = scene->lay & ((1<<20)-1);      /* Layer, by default visible*/  
1593         }
1594         
1595         base->lay= object->lay;
1596         
1597         base->flag = SELECT;
1598         object->id.us = 1; /* we will exist once in this scene */
1599
1600         BLI_addhead( &(scene->base), base );    /* finally, link new base to scene */
1601         
1602         /* make sure data and object materials are consistent */
1603         test_object_materials( (ID *)object->data );
1604         
1605         /* so we can deal with vertex groups */
1606         if (type == OB_MESH)
1607                 ((BPy_Mesh *)py_data)->object = object;
1608         
1609         return Object_CreatePyObject( object );
1610
1611 }
1612
1613 static PyObject *SceneObSeq_unlink( BPy_SceneObSeq * self, PyObject *args )
1614 {
1615         PyObject *pyobj;
1616         Object *blen_ob;
1617         Scene *scene;
1618         Base *base= NULL;
1619         
1620         SCENE_DEL_CHECK_PY(self->bpyscene);
1621         
1622         if (self->mode != EXPP_OBSEQ_NORMAL)
1623                 return (EXPP_ReturnPyObjError( PyExc_TypeError,
1624                                               "Cannot add new to objects.selection or objects.context!" ));     
1625         
1626         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &pyobj ) )
1627                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1628                                 "expected a python object as an argument" ) );
1629         
1630         blen_ob = ( ( BPy_Object * ) pyobj )->object;
1631         
1632         scene = self->bpyscene->scene;
1633         
1634         /* is the object really in the scene? */
1635         base = object_in_scene( blen_ob, scene);
1636         if( base ) { /* if it is, remove it */
1637                 if (scene->basact==base)
1638                         scene->basact= NULL;    /* in case the object was selected */
1639                 free_and_unlink_base_from_scene(scene, base);
1640                 Py_RETURN_TRUE;
1641         }
1642         Py_RETURN_FALSE;
1643 }
1644
1645 static PyObject *SceneObSeq_getActive(BPy_SceneObSeq *self)
1646 {
1647         Base *base;
1648         SCENE_DEL_CHECK_PY(self->bpyscene);
1649         
1650         if (self->mode!=EXPP_OBSEQ_NORMAL)
1651                         return (EXPP_ReturnPyObjError( PyExc_TypeError,
1652                                                 "cannot get active from objects.selected or objects.context" ));
1653         
1654         base= self->bpyscene->scene->basact;
1655         if (!base)
1656                 Py_RETURN_NONE;
1657         
1658         return Object_CreatePyObject( base->object );
1659 }
1660
1661 static int SceneObSeq_setActive(BPy_SceneObSeq *self, PyObject *value)
1662 {
1663         Base *base;
1664         
1665         SCENE_DEL_CHECK_INT(self->bpyscene);
1666         
1667         if (self->mode!=EXPP_OBSEQ_NORMAL)
1668                         return (EXPP_ReturnIntError( PyExc_TypeError,
1669                                                 "cannot set active from objects.selected or objects.context" ));
1670         
1671         if (value==Py_None) {
1672                 self->bpyscene->scene->basact= NULL;
1673                 return 0;
1674         }
1675         
1676         if (!BPy_Object_Check(value))
1677                 return (EXPP_ReturnIntError( PyExc_ValueError,
1678                                               "Object or None types can only be assigned to active!" ));
1679         
1680         base = object_in_scene( ((BPy_Object *)value)->object, self->bpyscene->scene );
1681         
1682         if (!base)
1683                 return (EXPP_ReturnIntError( PyExc_ValueError,
1684                                         "cannot assign an active object outside the scene." ));
1685         
1686         self->bpyscene->scene->basact= base;
1687         return 0;
1688 }
1689
1690 static PyObject *SceneObSeq_getCamera(BPy_SceneObSeq *self)
1691 {
1692         SCENE_DEL_CHECK_PY(self->bpyscene);
1693         
1694         if (self->mode!=EXPP_OBSEQ_NORMAL)
1695                         return (EXPP_ReturnPyObjError( PyExc_TypeError,
1696                                                 "cannot get camera from objects.selected or objects.context" ));
1697         
1698         return Object_CreatePyObject( self->bpyscene->scene->camera );
1699 }
1700
1701 static int SceneObSeq_setCamera(BPy_SceneObSeq *self, PyObject *value)
1702 {
1703         int ret;
1704
1705         SCENE_DEL_CHECK_INT(self->bpyscene);
1706         if (self->mode!=EXPP_OBSEQ_NORMAL)
1707                         return EXPP_ReturnIntError( PyExc_TypeError,
1708                                         "cannot set camera from objects.selected or objects.context" );
1709         
1710         ret = GenericLib_assignData(value, (void **) &self->bpyscene->scene->camera, 0, 0, ID_OB, 0);
1711         
1712         /* if this is the current scene, update its window now */
1713         if( ret == 0 && !G.background && self->bpyscene->scene == G.scene ) /* Traced a crash to redrawing while in background mode -Campbell */
1714                 copy_view3d_lock( REDRAW );
1715
1716 /* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
1717  * The same happens in bpython. */
1718
1719         return ret;
1720 }
1721
1722
1723 static struct PyMethodDef BPy_SceneObSeq_methods[] = {
1724         {"link", (PyCFunction)SceneObSeq_link, METH_VARARGS,
1725                 "link object to this scene"},
1726         {"new", (PyCFunction)SceneObSeq_new, METH_VARARGS,
1727                 "Create a new object in this scene from the obdata given and return a new object"},
1728         {"unlink", (PyCFunction)SceneObSeq_unlink, METH_VARARGS,
1729                 "unlinks the object from the scene"},
1730         {NULL, NULL, 0, NULL}
1731 };
1732
1733 /************************************************************************
1734  *
1735  * Python SceneObSeq_Type standard operations
1736  *
1737  ************************************************************************/
1738
1739 static void SceneObSeq_dealloc( BPy_SceneObSeq * self )
1740 {
1741         Py_DECREF(self->bpyscene);
1742         PyObject_DEL( self );
1743 }
1744
1745 static int SceneObSeq_compare( BPy_SceneObSeq * a, BPy_SceneObSeq * b )
1746 {
1747         return ( a->bpyscene->scene == b->bpyscene->scene && a->mode == b->mode) ? 0 : -1;      
1748 }
1749
1750 /*
1751  * repr function
1752  * callback functions building meaninful string to representations
1753  */
1754 static PyObject *SceneObSeq_repr( BPy_SceneObSeq * self )
1755 {
1756         if( !(self->bpyscene->scene) )
1757                 return PyString_FromFormat( "[Scene ObjectSeq Removed]" );
1758         else if (self->mode==EXPP_OBSEQ_SELECTED)
1759                 return PyString_FromFormat( "[Scene ObjectSeq Selected \"%s\"]",
1760                                                 self->bpyscene->scene->id.name + 2 );
1761         else if (self->mode==EXPP_OBSEQ_CONTEXT)
1762                 return PyString_FromFormat( "[Scene ObjectSeq Context \"%s\"]",
1763                                                 self->bpyscene->scene->id.name + 2 );
1764         
1765         /*self->mode==0*/
1766         return PyString_FromFormat( "[Scene ObjectSeq \"%s\"]",
1767                                         self->bpyscene->scene->id.name + 2 );
1768 }
1769
1770 static PyGetSetDef SceneObSeq_getseters[] = {
1771         {"selected",
1772          (getter)SceneObSeq_getObjects, (setter)SceneObSeq_setObjects,
1773          "sequence of selected objects",
1774          (void *)EXPP_OBSEQ_SELECTED},
1775         {"context",
1776          (getter)SceneObSeq_getObjects, (setter)SceneObSeq_setObjects,
1777          "sequence of user context objects",
1778          (void *)EXPP_OBSEQ_CONTEXT},
1779         {"active",
1780          (getter)SceneObSeq_getActive, (setter)SceneObSeq_setActive,
1781          "active object",
1782          NULL},
1783         {"camera",
1784          (getter)SceneObSeq_getCamera, (setter)SceneObSeq_setCamera,
1785          "camera object",
1786          NULL},
1787         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
1788 };
1789
1790 /*****************************************************************************/
1791 /* Python SceneObSeq_Type structure definition:                               */
1792 /*****************************************************************************/
1793 PyTypeObject SceneObSeq_Type = {
1794         PyObject_HEAD_INIT( NULL )  /* required py macro */
1795         0,                          /* ob_size */
1796         /*  For printing, in format "<module>.<name>" */
1797         "Blender SceneObSeq",           /* char *tp_name; */
1798         sizeof( BPy_SceneObSeq ),       /* int tp_basicsize; */
1799         0,                          /* tp_itemsize;  For allocation */
1800
1801         /* Methods to implement standard operations */
1802
1803         ( destructor ) SceneObSeq_dealloc,/* destructor tp_dealloc; */
1804         NULL,                       /* printfunc tp_print; */
1805         NULL,                       /* getattrfunc tp_getattr; */
1806         NULL,                       /* setattrfunc tp_setattr; */
1807         ( cmpfunc ) SceneObSeq_compare, /* cmpfunc tp_compare; */
1808         ( reprfunc ) SceneObSeq_repr,   /* reprfunc tp_repr; */
1809
1810         /* Method suites for standard classes */
1811
1812         NULL,                       /* PyNumberMethods *tp_as_number; */
1813         &SceneObSeq_as_sequence,            /* PySequenceMethods *tp_as_sequence; */
1814         NULL,                       /* PyMappingMethods *tp_as_mapping; */
1815
1816         /* More standard operations (here for binary compatibility) */
1817
1818         NULL,                       /* hashfunc tp_hash; */
1819         NULL,                       /* ternaryfunc tp_call; */
1820         NULL,                       /* reprfunc tp_str; */
1821         NULL,                       /* getattrofunc tp_getattro; */
1822         NULL,                       /* setattrofunc tp_setattro; */
1823
1824         /* Functions to access object as input/output buffer */
1825         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1826
1827   /*** Flags to define presence of optional/expanded features ***/
1828         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
1829
1830         NULL,                       /*  char *tp_doc;  Documentation string */
1831   /*** Assigned meaning in release 2.0 ***/
1832         /* call function for all accessible objects */
1833         NULL,                       /* traverseproc tp_traverse; */
1834
1835         /* delete references to contained objects */
1836         NULL,                       /* inquiry tp_clear; */
1837
1838   /***  Assigned meaning in release 2.1 ***/
1839   /*** rich comparisons ***/
1840         NULL,                       /* richcmpfunc tp_richcompare; */
1841
1842   /***  weak reference enabler ***/
1843         0,                          /* long tp_weaklistoffset; */
1844
1845   /*** Added in release 2.2 ***/
1846         /*   Iterators */
1847         ( getiterfunc) SceneObSeq_getIter, /* getiterfunc tp_iter; */
1848         ( iternextfunc ) SceneObSeq_nextIter, /* iternextfunc tp_iternext; */
1849
1850   /*** Attribute descriptor and subclassing stuff ***/
1851         BPy_SceneObSeq_methods,       /* struct PyMethodDef *tp_methods; */
1852         NULL,                       /* struct PyMemberDef *tp_members; */
1853         SceneObSeq_getseters,       /* struct PyGetSetDef *tp_getset; */
1854         NULL,                       /* struct _typeobject *tp_base; */
1855         NULL,                       /* PyObject *tp_dict; */
1856         NULL,                       /* descrgetfunc tp_descr_get; */
1857         NULL,                       /* descrsetfunc tp_descr_set; */
1858         0,                          /* long tp_dictoffset; */
1859         NULL,                       /* initproc tp_init; */
1860         NULL,                       /* allocfunc tp_alloc; */
1861         NULL,                       /* newfunc tp_new; */
1862         /*  Low-level free-memory routine */
1863         NULL,                       /* freefunc tp_free;  */
1864         /* For PyObject_IS_GC */
1865         NULL,                       /* inquiry tp_is_gc;  */
1866         NULL,                       /* PyObject *tp_bases; */
1867         /* method resolution order */
1868         NULL,                       /* PyObject *tp_mro;  */
1869         NULL,                       /* PyObject *tp_cache; */
1870         NULL,                       /* PyObject *tp_subclasses; */
1871         NULL,                       /* PyObject *tp_weaklist; */
1872         NULL
1873 };