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