218610a67e5684323ad1b282768226809f7a7b1e
[blender.git] / source / blender / python / api2_2x / Scene.c
1 /* 
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * This is a new part of Blender.
26  *
27  * Contributor(s): Willian P. Germano, Jacques Guignot, Joseph Gilbert
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30 */
31
32 #include <BKE_main.h>
33 #include <BKE_global.h>
34 #include <BKE_scene.h>
35 #include <BKE_library.h>
36 #include <BLI_blenlib.h>
37 #include <BSE_headerbuttons.h> /* for copy_scene */
38 #include <BIF_drawscene.h>               /* for set_scene */
39 #include <BIF_space.h>                           /* for copy_view3d_lock() */
40 #include <DNA_scriptlink_types.h>
41 #include <MEM_guardedalloc.h>  /* for MEM_callocN */
42 #include <mydevice.h>                                    /* for #define REDRAW */
43
44 #include "Object.h"
45 #include "bpy_types.h"
46 #include "constant.h"
47 #include "gen_utils.h"
48 #include "sceneRender.h"
49
50 #include "Scene.h"
51
52 static Base *EXPP_Scene_getObjectBase (Scene *scene, Object *object);
53 PyObject *M_Object_Get (PyObject *self, PyObject *args); /* from Object.c */
54
55 //----------------------------------- Python BPy_Scene defaults----------------------------------------------------------                                                                               
56 #define EXPP_SCENE_FRAME_MAX 18000
57 #define EXPP_SCENE_RENDER_WINRESOLUTION_MIN 4
58 #define EXPP_SCENE_RENDER_WINRESOLUTION_MAX 10000
59 //-----------------------Python API function prototypes for the Scene module------------------------------------
60 static PyObject *M_Scene_New (PyObject *self, PyObject *args,    PyObject *keywords);
61 static PyObject *M_Scene_Get (PyObject *self, PyObject *args);
62 static PyObject *M_Scene_GetCurrent (PyObject *self);
63 static PyObject *M_Scene_Unlink (PyObject *self, PyObject *arg);
64 //-----------------------Scene module doc strings---------------------------------------------------------------------------
65 static char M_Scene_doc[] =
66 "The Blender.Scene submodule";
67 static char M_Scene_New_doc[] =
68 "(name = 'Scene') - Create a new Scene called 'name' in Blender.";
69 static char M_Scene_Get_doc[] =
70 "(name = None) - Return the scene called 'name'. If 'name' is None, return a list with all Scenes.";
71 static char M_Scene_GetCurrent_doc[] =
72 "() - Return the currently active Scene in Blender.";
73 static char M_Scene_Unlink_doc[] =
74 "(scene) - Unlink (delete) scene 'Scene' from Blender. (scene) is of type Blender scene.";
75 //----------------------Scene module method def---------------------------------------------------------------------------
76 struct PyMethodDef M_Scene_methods[] = {
77         {"New",(PyCFunction)M_Scene_New, METH_VARARGS|METH_KEYWORDS,
78                                         M_Scene_New_doc},
79         {"Get",                                 M_Scene_Get,                             METH_VARARGS, M_Scene_Get_doc},
80         {"get",                                 M_Scene_Get,                             METH_VARARGS, M_Scene_Get_doc},
81         {"GetCurrent",(PyCFunction)M_Scene_GetCurrent,
82                                                                                                                  METH_NOARGS,  M_Scene_GetCurrent_doc},
83         {"getCurrent",(PyCFunction)M_Scene_GetCurrent,
84                                                                                                                  METH_NOARGS,  M_Scene_GetCurrent_doc},
85         {"Unlink",                      M_Scene_Unlink,                  METH_VARARGS, M_Scene_Unlink_doc},
86         {"unlink",                      M_Scene_Unlink,                  METH_VARARGS, M_Scene_Unlink_doc},
87         {NULL, NULL, 0, NULL}
88 };
89 //-----------------------BPy_Scene  method declarations-----------------------------------------------------------------
90 static PyObject *Scene_getName(BPy_Scene *self);
91 static PyObject *Scene_setName(BPy_Scene *self, PyObject *arg);
92 static PyObject *Scene_copy(BPy_Scene *self, PyObject *arg);
93 static PyObject *Scene_makeCurrent(BPy_Scene *self);
94 static PyObject *Scene_update(BPy_Scene *self, PyObject *args);
95 static PyObject *Scene_link(BPy_Scene *self, PyObject *args);
96 static PyObject *Scene_unlink(BPy_Scene *self, PyObject *args);
97 static PyObject *Scene_getChildren(BPy_Scene *self);
98 static PyObject *Scene_getCurrentCamera(BPy_Scene *self);
99 static PyObject *Scene_setCurrentCamera(BPy_Scene *self, PyObject *args);
100 static PyObject *Scene_getRenderingContext(BPy_Scene *self);
101 static PyObject *Scene_getScriptlinks(BPy_Scene *self, PyObject *args);
102
103 //deprecated methods
104 static PyObject *Scene_currentFrame(BPy_Scene *self, PyObject *args);
105 static PyObject *Scene_getWinSize(BPy_Scene *self);
106 static PyObject *Scene_setWinSize(BPy_Scene *self, PyObject *arg);
107 static PyObject *Scene_startFrame(BPy_Scene *self, PyObject *args);
108 static PyObject *Scene_endFrame(BPy_Scene *self, PyObject *args);
109 static PyObject *Scene_frameSettings (BPy_Scene *self, PyObject *args);
110 static PyObject *Scene_getRenderdir(BPy_Scene *self);
111 static PyObject *Scene_getBackbufdir(BPy_Scene *self);
112
113 //internal
114 static void Scene_dealloc (BPy_Scene *self);
115 static int Scene_setAttr (BPy_Scene *self, char *name, PyObject *v);
116 static int Scene_compare (BPy_Scene *a, BPy_Scene *b);
117 static PyObject *Scene_getAttr (BPy_Scene *self, char *name);
118 static PyObject *Scene_repr (BPy_Scene *self);
119 //-----------------------BPy_Scene method def-------------------------------------------------------------------------------
120 static PyMethodDef BPy_Scene_methods[] = {
121  /* name, method, flags, doc */
122         {"getName", (PyCFunction)Scene_getName, METH_NOARGS,
123                         "() - Return Scene name"},
124         {"setName", (PyCFunction)Scene_setName, METH_VARARGS,
125                                         "(str) - Change Scene name"},
126         {"copy",                (PyCFunction)Scene_copy, METH_VARARGS,
127                                         "(duplicate_objects = 1) - Return a copy of this scene\n"
128         "The optional argument duplicate_objects defines how the scene\n"
129         "children are duplicated:\n\t0: Link Objects\n\t1: Link Object Data"
130         "\n\t2: Full copy\n"},
131         {"makeCurrent", (PyCFunction)Scene_makeCurrent, METH_NOARGS,
132                                         "() - Make self the current scene"},
133         {"update", (PyCFunction)Scene_update, METH_VARARGS,
134                                         "(full = 0) - Update scene self.\n"
135                                         "full = 0: sort the base list of objects."
136                                         "full = 1: full update -- also regroups, does ipos, ikas, keys"},
137         {"link", (PyCFunction)Scene_link, METH_VARARGS,
138                                         "(obj) - Link Object obj to this scene"},
139         {"unlink", (PyCFunction)Scene_unlink, METH_VARARGS,
140                                         "(obj) - Unlink Object obj from this scene"},
141         {"getChildren", (PyCFunction)Scene_getChildren, METH_NOARGS,
142                                         "() - Return list of all objects linked to scene self"},
143         {"getCurrentCamera", (PyCFunction)Scene_getCurrentCamera, METH_NOARGS,
144                                         "() - Return current active Camera"},
145         {"getScriptlinks", (PyCFunction)Scene_getScriptlinks, METH_VARARGS,
146                                         "(eventname) - Get a list of this scene's scriptlinks (Text names) of the given type\n"
147         "(eventname) - string: FrameChanged, OnLoad or Redraw."},
148         {"setCurrentCamera", (PyCFunction)Scene_setCurrentCamera, METH_VARARGS,
149                                         "() - Set the currently active Camera"},
150         //DEPRECATED
151         {"getWinSize", (PyCFunction)Scene_getWinSize, METH_NOARGS,
152                         "() - Return Render window [x,y] dimensions"},
153         {"setWinSize", (PyCFunction)Scene_setWinSize, METH_VARARGS,
154                                         "(str) - Change Render window [x,y] dimensions"},
155         {"startFrame", (PyCFunction)Scene_startFrame, METH_VARARGS,
156                                         "(frame) - If frame is given, the start frame is set and"
157                                                                         "\nreturned in any case"},
158         {"endFrame", (PyCFunction)Scene_endFrame, METH_VARARGS,
159                                         "(frame) - If frame is given, the end frame is set and"
160                                                                         "\nreturned in any case"},
161         {"frameSettings", (PyCFunction)Scene_frameSettings, METH_VARARGS,
162                                         "(start, end, current) - Sets or retrieves the Scene's frame"
163                                         " settings.\nIf the frame arguments are specified, they are set. "
164                                         "A tuple (start, end, current) is returned in any case."},
165         {"getRenderdir", (PyCFunction)Scene_getRenderdir, METH_NOARGS,
166                                         "() - Return directory where rendered images are saved to"},
167         {"getBackbufdir", (PyCFunction)Scene_getBackbufdir, METH_NOARGS,
168                                         "() - Return location of the backbuffer image"},
169         {"getRenderingContext", (PyCFunction)Scene_getRenderingContext, METH_NOARGS,
170                                         "() - Get the rendering context for the scene and return it as a BPy_RenderData"},
171         {"currentFrame", (PyCFunction)Scene_currentFrame, METH_VARARGS,
172                                         "(frame) - If frame is given, the current frame is set and"
173                                                                         "\nreturned in any case"},
174         {NULL, NULL, 0, NULL}
175 };
176 //-----------------------BPy_Scene method def-------------------------------------------------------------------------
177 PyTypeObject Scene_Type =
178 {
179         PyObject_HEAD_INIT(NULL)
180         0,                                                              /* ob_size */
181         "Scene",                                                /* tp_name */
182         sizeof (BPy_Scene),                             /* tp_basicsize */
183         0,                                                              /* tp_itemsize */
184         /* methods */
185         (destructor)Scene_dealloc,              /* tp_dealloc */
186         0,                                                              /* tp_print */
187         (getattrfunc)Scene_getAttr,             /* tp_getattr */
188         (setattrfunc)Scene_setAttr,             /* tp_setattr */
189         (cmpfunc)Scene_compare,                 /* tp_compare */
190         (reprfunc)Scene_repr,                   /* tp_repr */
191         0,                                                              /* tp_as_number */
192         0,                                                              /* tp_as_sequence */
193         0,                                                              /* tp_as_mapping */
194         0,                                                              /* tp_as_hash */
195         0,0,0,0,0,0,
196         0,                                                              /* tp_doc */ 
197         0,0,0,0,0,0,
198         BPy_Scene_methods,                              /* tp_methods */
199         0,                                                              /* tp_members */
200 };
201 //-----------------------Scene module Init())--------------------------------------------------------------------------------
202 PyObject *Scene_Init (void)
203 {
204         PyObject        *submodule;
205         PyObject *dict;
206
207         Scene_Type.ob_type = &PyType_Type;
208         submodule = Py_InitModule3("Blender.Scene",     M_Scene_methods, M_Scene_doc);
209
210         dict = PyModule_GetDict (submodule);
211     PyDict_SetItemString (dict, "Render", Render_Init ());
212
213         return submodule;
214 }
215 //-----------------------Scene module internal callbacks------------------------------------------------------------
216 //-----------------------dealloc-----------------------------------------------------------------------------------------------------
217 static void Scene_dealloc (BPy_Scene *self)
218 {
219         PyObject_DEL (self);
220 }
221 //-----------------------getAttr-----------------------------------------------------------------------------------------------------
222 static PyObject *Scene_getAttr (BPy_Scene *self, char *name)
223 {
224         PyObject *attr = Py_None;
225
226         if (strcmp(name, "name") == 0)
227                 attr = PyString_FromString(self->scene->id.name+2);
228
229         else if (strcmp(name, "__members__") == 0)
230                 attr = Py_BuildValue("[s]", "name");
231
232
233         if (!attr)
234                 return (EXPP_ReturnPyObjError (PyExc_MemoryError,
235                                                                                         "couldn't create PyObject"));
236
237         if (attr != Py_None) return attr; /* member attribute found, return it */
238
239         /* not an attribute, search the methods table */
240         return Py_FindMethod(BPy_Scene_methods, (PyObject *)self, name);
241 }
242 //-----------------------setAttr-----------------------------------------------------------------------------------------------------
243 static int Scene_setAttr (BPy_Scene *self, char *name, PyObject *value)
244 {
245         PyObject *valtuple; 
246         PyObject *error = NULL;
247
248 /* We're playing a trick on the Python API users here.  Even if they use
249  * Scene.member = val instead of Scene.setMember(val), we end up using the
250  * function anyway, since it already has error checking, clamps to the right
251  * interval and updates the Blender Scene structure when necessary. */
252
253 /* First we put "value" in a tuple, because we want to pass it to functions
254  * that only accept PyTuples. Using "N" doesn't increment value's ref count */
255         valtuple = Py_BuildValue("(O)", value);
256
257         if (!valtuple) /* everything OK with our PyObject? */
258                 return EXPP_ReturnIntError(PyExc_MemoryError,
259                                                                                                  "SceneSetAttr: couldn't create PyTuple");
260
261 /* Now we just compare "name" with all possible BPy_Scene member variables */
262         if (strcmp (name, "name") == 0)
263                 error = Scene_setName (self, valtuple);
264
265         else { /* Error: no member with the given name was found */
266                 Py_DECREF(valtuple);
267                 return (EXPP_ReturnIntError (PyExc_AttributeError, name));
268         }
269
270 /* valtuple won't be returned to the caller, so we need to DECREF it */
271         Py_DECREF(valtuple);
272
273         if (error != Py_None) return -1;
274
275 /* Py_None was incref'ed by the called Scene_set* function. We probably
276  * don't need to decref Py_None (!), but since Python/C API manual tells us
277  * to treat it like any other PyObject regarding ref counting ... */
278         Py_DECREF(Py_None);
279         return 0; /* normal exit */
280 }
281 //-----------------------compare-----------------------------------------------------------------------------------------------------
282 static int Scene_compare (BPy_Scene *a, BPy_Scene *b)
283 {
284         Scene *pa = a->scene, *pb = b->scene;
285         return (pa == pb) ? 0:-1;
286 }
287 //----------------------repr--------------------------------------------------------------------------------------------------------------
288 static PyObject *Scene_repr (BPy_Scene *self)
289 {
290         return PyString_FromFormat("[Scene \"%s\"]", self->scene->id.name+2);
291 }
292 //-----------------------CreatePyObject----------------------------------------------------------------------------------
293 PyObject *Scene_CreatePyObject (Scene *scene)
294 {
295         BPy_Scene *pyscene;
296
297         pyscene = (BPy_Scene *)PyObject_NEW (BPy_Scene, &Scene_Type);
298
299         if (!pyscene)
300                 return EXPP_ReturnPyObjError (PyExc_MemoryError,
301                                                 "couldn't create BPy_Scene object");
302
303         pyscene->scene = scene;
304
305         return (PyObject *)pyscene;
306 }
307 //-----------------------CheckPyObject----------------------------------------------------------------------------------
308 int Scene_CheckPyObject (PyObject *pyobj)
309 {
310         return (pyobj->ob_type == &Scene_Type);
311 }
312 //-----------------------FromPyObject----------------------------------------------------------------------------------
313 Scene *Scene_FromPyObject (PyObject *pyobj)
314 {
315         return ((BPy_Scene *)pyobj)->scene;
316 }
317 //-----------------------GetSceneByName()--------------------------------------------------------------------------------------------
318 /* Description: Returns the object with the name specified by the argument      name. 
319 Note that the calling function has to remove the first two characters of the object name. 
320 These two characters    specify the type of the object (OB, ME, WO, ...)The function 
321 will return NULL when no object with the given  name is found.   */
322 Scene * GetSceneByName (char * name)
323 {
324         Scene   * scene_iter;
325
326         scene_iter = G.main->scene.first;
327         while (scene_iter)
328         {
329                 if (StringEqual (name, GetIdName (&(scene_iter->id))))
330                 {
331                         return (scene_iter);
332                 }
333                 scene_iter = scene_iter->id.next;
334         }
335
336         /* There is no object with the given name */
337         return (NULL);
338 }
339 //-----------------------EXPP_Scene_getObjectBase()--------------------------------------------------------------------------------------------
340 Base *EXPP_Scene_getObjectBase(Scene *scene, Object *object)
341 {
342         Base *base = scene->base.first;
343
344         while (base) {
345
346                 if (object == base->object) return base; /* found it? */
347
348                 base = base->next;
349         }
350
351         return NULL; /* object isn't linked to this scene */
352 }
353 //-----------------------Scene module function defintions----------------------------------------------------------------------
354 //-----------------------Scene.New()--------------------------------------------------------------------------------------------------
355 static PyObject *M_Scene_New(PyObject *self, PyObject *args, PyObject *kword)
356 {
357         char             *name = "Scene";
358         char             *kw[] = {"name", NULL};
359         PyObject *pyscene; /* for the Scene object wrapper in Python */
360         Scene            *blscene; /* for the actual Scene we create in Blender */
361
362         if (!PyArg_ParseTupleAndKeywords(args, kword, "|s", kw, &name))
363                 return (EXPP_ReturnPyObjError (PyExc_AttributeError,
364                                                 "expected a string or an empty argument list"));
365
366         blscene = add_scene(name); /* first create the Scene in Blender */
367
368         if (blscene){ 
369           /* normally, for most objects, we set the user count to zero here.
370            * Scene is different than most objs since it is the container
371            * for all the others. Since add_scene() has already set 
372            * the user count to one, we leave it alone.
373            */ 
374
375           /* now create the wrapper obj in Python */
376           pyscene = Scene_CreatePyObject (blscene);
377         }
378         else
379                 return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
380                                                                                                                 "couldn't create Scene obj in Blender"));
381
382         if (pyscene == NULL)
383                 return (EXPP_ReturnPyObjError (PyExc_MemoryError,
384                                                                                                                 "couldn't create Scene PyObject"));
385
386         return pyscene;
387 }
388 //-----------------------Scene.Get()--------------------------------------------------------------------------------------------------
389 static PyObject *M_Scene_Get(PyObject *self, PyObject *args)
390 {
391         char    *name = NULL;
392         Scene *scene_iter;
393
394         if (!PyArg_ParseTuple(args, "|s", &name))
395                 return (EXPP_ReturnPyObjError (PyExc_TypeError,
396                                                 "expected string argument (or nothing)"));
397
398         scene_iter = G.main->scene.first;
399
400         if (name) { /* (name) - Search scene by name */
401
402                 PyObject *wanted_scene = NULL;
403
404                 while ((scene_iter) && (wanted_scene == NULL)) {
405
406                         if (strcmp (name, scene_iter->id.name+2) == 0)
407                                 wanted_scene = Scene_CreatePyObject (scene_iter);
408
409                         scene_iter = scene_iter->id.next;
410                 }
411
412                 if (wanted_scene == NULL) { /* Requested scene doesn't exist */
413                         char error_msg[64];
414                         PyOS_snprintf(error_msg, sizeof(error_msg),
415                                                                                         "Scene \"%s\" not found", name);
416                         return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg));
417                 }
418
419                 return wanted_scene;
420         }
421
422         else { /* () - return a list with wrappers for all scenes in Blender */
423                 int index = 0;
424                 PyObject *sce_pylist, *pyobj;
425
426                 sce_pylist = PyList_New (BLI_countlist (&(G.main->scene)));
427
428                 if (sce_pylist == NULL)
429                         return (EXPP_ReturnPyObjError (PyExc_MemoryError,
430                                                         "couldn't create PyList"));
431
432                 while (scene_iter) {
433                         pyobj = Scene_CreatePyObject (scene_iter);
434
435                         if (!pyobj)
436                                 return (EXPP_ReturnPyObjError (PyExc_MemoryError,
437                                                                         "couldn't create PyString"));
438
439                         PyList_SET_ITEM (sce_pylist, index, pyobj);
440
441                         scene_iter = scene_iter->id.next;
442                         index++;
443                 }
444
445                 return sce_pylist;
446         }
447 }
448 //-----------------------Scene.GetCurrent()---------------------------------------------------------------------------------------
449 static PyObject *M_Scene_GetCurrent (PyObject *self)
450 {
451         return Scene_CreatePyObject ((Scene *)G.scene);
452 }
453 //-----------------------Scene.Unlink()--------------------------------------------------------------------------------------------
454 static PyObject *M_Scene_Unlink (PyObject *self, PyObject *args)
455
456         PyObject *pyobj;
457         Scene            *scene;
458
459         if (!PyArg_ParseTuple (args, "O!", &Scene_Type, &pyobj))
460                                 return EXPP_ReturnPyObjError (PyExc_TypeError,
461                                                                 "expected Scene PyType object");
462
463         scene = ((BPy_Scene *)pyobj)->scene;
464
465         if (scene == G.scene)
466                                 return EXPP_ReturnPyObjError (PyExc_SystemError,
467                                                                 "current Scene cannot be removed!");
468
469         free_libblock(&G.main->scene, scene);
470
471         Py_INCREF(Py_None);
472         return Py_None;
473 }
474 //-----------------------BPy_Scene function defintions-----------------------------------------------------------------------
475 //-----------------------Scene.getName()-----------------------------------------------------------------------------------------
476 static PyObject *Scene_getName(BPy_Scene *self)
477 {
478         PyObject *attr = PyString_FromString(self->scene->id.name+2);
479
480         if (attr) return attr;
481
482         return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
483                                                                                                                                          "couldn't get Scene.name attribute"));
484 }
485 //-----------------------Scene.setName()-----------------------------------------------------------------------------------------
486 static PyObject *Scene_setName(BPy_Scene *self, PyObject *args)
487 {
488         char *name;
489         char buf[21];
490
491         if (!PyArg_ParseTuple(args, "s", &name))
492                 return (EXPP_ReturnPyObjError (PyExc_TypeError,
493                                                                                                                                                  "expected string argument"));
494
495         PyOS_snprintf(buf, sizeof(buf), "%s", name);
496
497         rename_id(&self->scene->id, buf);
498
499         Py_INCREF(Py_None);
500         return Py_None;
501 }
502 //-----------------------Scene.copy()-----------------------------------------------------------------------------------------
503 static PyObject *Scene_copy (BPy_Scene *self, PyObject *args)
504 {
505         short dup_objs = 1;
506         Scene *scene = self->scene;
507
508         if (!scene)
509                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
510                                                 "Blender Scene was deleted!");
511
512         if (!PyArg_ParseTuple (args, "|h", &dup_objs))
513                 return EXPP_ReturnPyObjError (PyExc_TypeError,
514                                                 "expected int in [0,2] or nothing as argument");
515
516         return Scene_CreatePyObject (copy_scene (scene, dup_objs));
517 }
518 //-----------------------Scene.makeCurrent()-----------------------------------------------------------------------------------------
519 static PyObject *Scene_makeCurrent (BPy_Scene *self)
520 {
521         Scene *scene = self->scene;
522
523         if (scene) set_scene (scene);
524
525         Py_INCREF (Py_None);
526         return Py_None;
527 }
528 //-----------------------Scene.update()-----------------------------------------------------------------------------------------
529 static PyObject *Scene_update (BPy_Scene *self, PyObject *args)
530 {
531         Scene *scene = self->scene;
532         int full = 0;
533
534         if (!scene)
535                         return EXPP_ReturnPyObjError (PyExc_RuntimeError,
536                                                         "Blender Scene was deleted!");
537
538         if (!PyArg_ParseTuple (args, "|i", &full))
539                         return EXPP_ReturnPyObjError (PyExc_TypeError,
540                                                         "expected nothing or int (0 or 1) argument");
541
542 /* Under certain circunstances, sort_baselist *here* can crash Blender.
543  * A "RuntimeError: max recursion limit" happens when a scriptlink
544  * on frame change has scene.update(1).
545  * Investigate better how to avoid this. */
546         if (!full)
547                 sort_baselist (scene);
548
549         else if (full == 1)
550                         set_scene_bg (scene);
551
552         else
553                 return EXPP_ReturnPyObjError (PyExc_ValueError,
554                         "in method scene.update(full), full should be:\n"
555                         "0: to only sort scene elements (old behavior); or\n"
556                         "1: for a full update (regroups, does ipos, ikas, keys, etc.)");
557
558         Py_INCREF (Py_None);
559         return Py_None;
560 }
561 //-----------------------Scene.link()-----------------------------------------------------------------------------------------------------
562 static PyObject *Scene_link (BPy_Scene *self, PyObject *args)
563 {
564         Scene *scene = self->scene;
565         BPy_Object *bpy_obj;
566
567         if (!scene)
568                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
569                         "Blender Scene was deleted!");
570
571         if (!PyArg_ParseTuple (args, "O!", &Object_Type, &bpy_obj))
572                 return EXPP_ReturnPyObjError (PyExc_TypeError,
573                         "expected Object argument");
574
575         else { /* Ok, all is fine, let's try to link it */
576                 Object *object = bpy_obj->object;
577                 Base *base;
578
579                 /* We need to link the object to a 'Base', then link this base
580                  * to the scene.        See DNA_scene_types.h ... */
581
582                 /* First, check if the object isn't already in the scene */
583                 base = EXPP_Scene_getObjectBase (scene, object);
584                 /* if base is not NULL ... */
585                 if (base) /* ... the object is already in one of the Scene Bases */
586                         return EXPP_ReturnPyObjError (PyExc_RuntimeError,
587                                                         "object already in scene!");
588
589                 /* not linked, go get mem for a new base object */
590
591                 base = MEM_callocN(sizeof(Base), "newbase");
592  
593                 if (!base)
594                         return EXPP_ReturnPyObjError (PyExc_MemoryError,
595                                                         "couldn't allocate new Base for object");
596
597                 /* check if this object has obdata, case not, try to create it */
598                 if (!object->data && (object->type != OB_EMPTY))
599                         EXPP_add_obdata(object); /* returns -1 on error, defined in Object.c */
600
601                 base->object = object; /* link object to the new base */
602                 base->lay = object->lay;
603                 base->flag = object->flag;
604
605                 object->id.us += 1; /* incref the object user count in Blender */
606
607                 BLI_addhead(&scene->base, base); /* finally, link new base to scene */
608         }
609
610         Py_INCREF (Py_None);
611         return Py_None;
612 }
613 //-----------------------Scene.unlink()-----------------------------------------------------------------------------------------------------
614 static PyObject *Scene_unlink (BPy_Scene *self, PyObject *args)
615
616         BPy_Object *bpy_obj = NULL;
617         Object *object;
618         Scene *scene = self->scene;
619         Base *base;
620         short retval = 0;
621
622         if (!scene)
623                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
624                                                 "Blender scene was deleted!");
625
626         if (!PyArg_ParseTuple(args, "O!", &Object_Type, &bpy_obj))
627                 return EXPP_ReturnPyObjError (PyExc_TypeError,
628                                                 "expected Object as argument");
629
630         object = bpy_obj->object;
631
632         /* is the object really in the scene? */
633         base = EXPP_Scene_getObjectBase(scene, object);
634          
635         if (base) { /* if it is, remove it: */
636                 BLI_remlink(&scene->base, base);
637                 object->id.us -= 1;
638                 MEM_freeN (base);
639                 scene->basact = 0; /* in case the object was selected */
640                 retval = 1;
641         }
642
643         return Py_BuildValue ("i", PyInt_FromLong (retval));
644 }
645 //-----------------------Scene.getChildren()-----------------------------------------------------------------------------------------------------
646 static PyObject *Scene_getChildren (BPy_Scene *self)
647 {       
648         Scene *scene = self->scene;
649         PyObject *pylist= PyList_New(0);
650         PyObject *bpy_obj;
651         Object *object;
652         Base *base;
653
654         if (!scene)
655                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
656                                                 "Blender Scene was deleted!");
657
658         base = scene->base.first;
659
660         while (base) {
661                 object = base->object;
662
663                 bpy_obj = M_Object_Get(Py_None,
664                                                                                 Py_BuildValue ("(s)", object->id.name+2));
665
666                 if (!bpy_obj)
667                         return EXPP_ReturnPyObjError (PyExc_RuntimeError,
668                                                                 "couldn't create new object wrapper");
669
670                 PyList_Append (pylist, bpy_obj);
671                 Py_XDECREF (bpy_obj); /* PyList_Append incref'ed it */
672
673                 base = base->next;
674         }
675
676         return pylist;
677 }
678 //-----------------------Scene.getCurrentCamera()---------------------------------------------------------------------------------------
679 static PyObject *Scene_getCurrentCamera (BPy_Scene *self)
680 {       
681         Object *cam_obj;
682         Scene *scene = self->scene;
683
684         if (!scene)
685                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
686                                                 "Blender Scene was deleted!");
687
688         cam_obj = scene->camera;
689
690         if (cam_obj) /* if found, return a wrapper for it */
691                 return M_Object_Get (Py_None, Py_BuildValue ("(s)", cam_obj->id.name+2));
692
693         Py_INCREF(Py_None); /* none found */
694         return Py_None;
695 }
696 //-----------------------Scene.setCurrentCamera()---------------------------------------------------------------------------------------
697 static PyObject *Scene_setCurrentCamera (BPy_Scene *self, PyObject *args)
698 {
699         Object *object;
700         BPy_Object *cam_obj;
701         Scene *scene = self->scene;
702
703         if (!scene)
704                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
705                                                 "Blender Scene was deleted!");
706
707         if (!PyArg_ParseTuple(args, "O!", &Object_Type, &cam_obj))
708                 return EXPP_ReturnPyObjError (PyExc_TypeError,
709                                                 "expected Camera Object as argument");
710
711         object = cam_obj->object;
712
713         scene->camera = object; /* set the current Camera */
714
715         /* if this is the current scene, update its window now */
716         if (scene == G.scene) copy_view3d_lock(REDRAW);
717
718 /* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
719  * The same happens in bpython. */
720
721         Py_INCREF(Py_None);
722         return Py_None;
723 }
724 //-----------------------Scene.getRenderingContext()----------------------------------------------------------------------
725 static PyObject *Scene_getRenderingContext (BPy_Scene *self)
726 {       
727         if (!self->scene)
728                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
729                                                 "Blender Scene was deleted!");
730
731         return RenderData_CreatePyObject(self->scene);
732 }
733
734 /* Scene.getScriptlinks */
735 static PyObject *Scene_getScriptlinks (BPy_Scene *self, PyObject *args)
736 {
737         Scene *scene = self->scene;
738         char *eventname = NULL;
739         int event = 0;
740         ScriptLink *slink = &(scene)->scriptlink;
741
742         if (!scene)
743                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
744                                                 "Blender Scene was deleted!");
745
746         if (!PyArg_ParseTuple(args, "s", &eventname))
747                 return EXPP_ReturnPyObjError (PyExc_TypeError,
748                                                 "expected event name (string) as argument");
749
750         if (!strcmp(eventname, "FrameChanged"))
751                 event = SCRIPT_FRAMECHANGED;
752         else if (!strcmp(eventname, "OnLoad"))
753                 event = SCRIPT_ONLOAD;
754         else if (!strcmp(eventname, "Redraw"))
755                 event = SCRIPT_REDRAW;
756         else
757                 return EXPP_ReturnPyObjError (PyExc_AttributeError,
758                                                 "unknown event");
759
760         /* actually !scriptlink shouldn't happen ... */
761         if (!slink || !slink->totscript) {
762                 Py_INCREF(Py_None);
763                 return Py_None;
764         }
765         else {
766                 PyObject *list = PyList_New(0);
767                 int i;
768
769                 if (!list)
770                         return EXPP_ReturnPyObjError (PyExc_MemoryError,
771                                 "couldn't create PyList!");
772
773                 for (i = 0; i < slink->totscript; i++) {
774                         if ((slink->flag[i] == event) && slink->scripts[i])
775                                 PyList_Append(list, PyString_FromString(slink->scripts[i]->name+2));
776                 }
777
778                 return list;
779         }
780 }
781
782 /*****************************************************************************/
783 // DEPRECATED   
784 /*****************************************************************************/
785 //-----------------------Scene.getRenderdir ()----------------------------------------------------------------------
786 static PyObject *Scene_getRenderdir (BPy_Scene *self)
787 {
788                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
789                         "Depricated:use RenderData.getRenderPath()");
790 }
791 //-----------------------Scene.getBackbufdir ()----------------------------------------------------------------------
792 static PyObject *Scene_getBackbufdir (BPy_Scene *self)
793 {
794                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
795                         "Depricated:use RenderData.getBackbufPath()");
796 }
797 //-----------------------Scene.startFrame ()----------------------------------------------------------------------
798 static PyObject *Scene_startFrame (BPy_Scene *self, PyObject *args)
799 {
800                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
801                         "Depricated:use RenderData.startFrame()");
802 }
803 //-----------------------Scene.endFrame ()----------------------------------------------------------------------
804 static PyObject *Scene_endFrame (BPy_Scene *self, PyObject *args)
805 {
806                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
807                         "Depricated:use RenderData.endFrame()");
808 }
809 //-----------------------Scene.getWinSize ()----------------------------------------------------------------------
810 static PyObject *Scene_getWinSize(BPy_Scene *self)
811 {
812                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
813                         "Depricated:use RenderData.imageSizeX() and RenderData.imageSizeY");
814 }
815 //-----------------------Scene.setWinSize()----------------------------------------------------------------------
816 static PyObject *Scene_setWinSize(BPy_Scene *self, PyObject *args)
817 {
818                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
819                         "Depricated:use RenderData.imageSizeX() and RenderData.imageSizeY");
820 }
821 //-----------------------Scene.frameSettings()----------------------------------------------------------------------
822 static PyObject *Scene_frameSettings (BPy_Scene *self, PyObject *args)
823 {       
824                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
825                         "Depricated:use RenderData.startFrame(),  RenderData.endFrame, RenderData.currentFrame");
826 }
827 //-----------------------Scene.currentFrame()-----------------------------------------------------------------------------------------
828 static PyObject *Scene_currentFrame (BPy_Scene *self, PyObject *args)
829 {
830                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
831                         "Depricated:use RenderData.currentFrame");
832 }