diff options
Diffstat (limited to 'source/blender/bpython/intern/BPY_scene.c')
-rw-r--r-- | source/blender/bpython/intern/BPY_scene.c | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/source/blender/bpython/intern/BPY_scene.c b/source/blender/bpython/intern/BPY_scene.c new file mode 100644 index 00000000000..19e992e6bb1 --- /dev/null +++ b/source/blender/bpython/intern/BPY_scene.c @@ -0,0 +1,506 @@ +/** Scene module; access to Scene objects in Blender + * + * Scene objects are no longer DataBlock objects, but referred + * by name. This makes it a little slower, but safer - Scene properties + * can no longer be accessed after a Scene was deleted. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * + */ + +#include "Python.h" + +#include "BKE_scene.h" +#include "BIF_drawscene.h" + +#include "BSE_headerbuttons.h" + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "opy_datablock.h" +#include "b_interface.h" + +#include "BPY_macros.h" +#include "BPY_window.h" + +/* DEFINES */ + +#define CHECK_VALIDSCENE(x) CHECK_VALIDDATA(x, \ + "Scene was deleted!") + +#define PyScene_AsScene(x) \ + getSceneByName(((PyScene *) x)->name) + +/* PROTOS */ + +PyObject *PyScene_FromScene(Scene *scene); + +/************************/ +/* Helper routines */ + +/* returns a python list of the objects of the Base 'base' */ + +static PyObject *objectlist_from_base(Base *base) +{ + PyObject *pylist= PyList_New(0); + PyObject *b; + + while (base) { + b = (PyObject *) DataBlock_fromData(base->object); + PyList_Append(pylist, b); + Py_XDECREF(b); // because PyList_Append increfs! + base = base->next; + } + return pylist; +} + +/* Scene object */ + +typedef struct { + PyObject_VAR_HEAD + char name[32]; +} PyScene; + +static PyObject *newPyScene(char *name); + +/** Returns scene by name. Can be NULL if not found */ +Scene *getSceneByName(char *name) +{ + return (Scene *) getFromList(getSceneList(), name); +} + +/************************/ +/* Scene object methods */ + +static char Scene_getChildren_doc[] = +"() - returns list of scene children objects"; + +static PyObject *Scene_getChildren(PyObject *self, PyObject *args) +{ + Scene *scene = PyScene_AsScene(self); + + CHECK_VALIDSCENE(scene) + + BPY_TRY(PyArg_ParseTuple(args, "")); + return objectlist_from_base(scene->base.first); +} + +static char Scene_getCurrentCamera_doc[] = +"() - returns current active camera"; + +static PyObject *Scene_getCurrentCamera(PyObject *self, PyObject *args) +{ + Scene *scene = PyScene_AsScene(self); + Object *object; + + CHECK_VALIDSCENE(scene) + + object = scene->camera; + if (!object) { + Py_INCREF(Py_None); + return Py_None; + } + return DataBlock_fromData(object); +} + +static char Scene_setCurrentCamera_doc[] = +"(camera) - sets current active camera. 'camera' must be a valid camera\n\ +Object"; + +static PyObject *Scene_setCurrentCamera(PyObject *self, PyObject *args) +{ + Scene *scene = PyScene_AsScene(self); + Object *object; + DataBlock *block; + + CHECK_VALIDSCENE(scene) + + BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &block)); + if (!DataBlock_isType(block, ID_OB)) { + PyErr_SetString(PyExc_TypeError, "Object type expected!"); + return NULL; + } + + object = PYBLOCK_AS_OBJECT(block); + + scene->camera = object; + if (scene_getCurrent() == scene) // update current scene display + window_update_curCamera(object); + + Py_INCREF(Py_None); + return Py_None; +} + +#define SCENE_GETDIR(name, elem) \ +static PyObject *Scene_get##name(PyObject *self, PyObject *args) \ +{ \ + Scene *scene = PyScene_AsScene(self); \ + CHECK_VALIDSCENE(scene) \ + return PyString_FromString(scene->elem); \ +} \ + +static char Scene_getRenderdir_doc[] = +"() - returns directory where rendered images are saved to"; + +SCENE_GETDIR(Renderdir, r.pic) + +static char Scene_getBackbufdir_doc[] = +"() - returns the Backbuffer images location"; + +SCENE_GETDIR(Backbufdir, r.backbuf) + +#define INVALID_FRAME -99999 + +static char Scene_frameSettings_doc[] = +"(start, end, current) - sets the scene's frame settings:\n\ + start : start frame\n\ + end : end frame\n\ + current: current frame\n\ +If a frame value is negative, it is not set.\n\ +\n\ +Return value: the current frame settings (start, end, current)"; + +static PyObject *Scene_frameSettings(PyObject *self, PyObject *args) +{ + RenderData *rd = 0; + int current = INVALID_FRAME; + int start = INVALID_FRAME; + int end = INVALID_FRAME; + Scene *scene = PyScene_AsScene(self); + + CHECK_VALIDSCENE(scene) + + rd = &scene->r; + + BPY_TRY(PyArg_ParseTuple(args, "|iii", &start, &end, ¤t)); + if (start > 0) { + rd->sfra = start; + } + if (end > 0) { + rd->efra = end; + } + if (current > 0) { + rd->cfra = current; + } + return Py_BuildValue("(iii)", rd->sfra, rd->efra, rd->cfra); +} + + +static char Scene_makeCurrent_doc[] = +"() - makes Scene the current Scene"; + +static PyObject *Scene_makeCurrent(PyObject *self, PyObject *args) +{ + Scene *scene = PyScene_AsScene(self); + + CHECK_VALIDSCENE(scene) + + set_scene(scene); + Py_INCREF(Py_None); + return Py_None; +} + +static char Scene_copy_doc[] = +"(duplicate_objects = 1) - make a copy of a scene\n\ +'The optional argument defines, how the scene's children objects are\n\ +duplicated:\n\ +\n\ +0: Link Objects\n\ +1: Link Object data\n\ +2: Full Copy"; + +static PyObject *Scene_copy(PyObject *self, PyObject *args) +{ + Scene *scene = PyScene_AsScene(self); + + int dup_objects = 0; + + CHECK_VALIDSCENE(scene) + + BPY_TRY(PyArg_ParseTuple(args, "|i", &dup_objects)); + + return PyScene_FromScene(copy_scene(scene, dup_objects)); +} + +static char Scene_update_doc[]= "() - Update scene\n\ +This function explicitely resorts the base list of a newly created object\n\ +hierarchy."; + +static PyObject *Scene_update(PyObject *self, PyObject *args) +{ + Scene *scene = PyScene_AsScene(self); + + CHECK_VALIDSCENE(scene) + + BPY_TRY(PyArg_ParseTuple(args, "")); + sort_baselist(scene); + Py_INCREF(Py_None); + return Py_None; +} + +static char Scene_link_doc[]= "(object) - Links object to scene"; + +/** Links an object with a scene */ +static PyObject *Scene_link(PyObject *self, PyObject *args) +{ + DataBlock *block; + Object *object; + Scene *scene = PyScene_AsScene(self); + CHECK_VALIDSCENE(scene) + + BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &block)); + if (DataBlock_type(block) != ID_OB) { + PyErr_SetString(PyExc_TypeError, "link: invalid Object type"); + return NULL; + } + object = PYBLOCK_AS_OBJECT(block); + if (!scene_linkObject(scene, object)) + { + PyErr_SetString(PyExc_RuntimeError, "Object already in scene!"); + return NULL; + } + Py_INCREF(Py_None); + return Py_None; +} + +/** unlinks (removes) an object from a scene */ + +static char Scene_unlink_doc[]= "(object) - Unlinks object from scene"; + +static PyObject *Scene_unlink(PyObject *self, PyObject *args) +{ + PyObject *retval; + DataBlock *block; + Object *object; + Scene *scene = PyScene_AsScene(self); + CHECK_VALIDSCENE(scene) + + BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &block)); + if (DataBlock_type(block) != ID_OB) { + PyErr_SetString(PyExc_TypeError, "unlink: invalid Object type"); + return NULL; + } + object = PYBLOCK_AS_OBJECT(block); + + if (!scene_unlinkObject(scene, object)) + retval = Py_BuildValue("i", 0); + else + retval = Py_BuildValue("i", 1); + Py_INCREF(retval); + return retval; +} + +#undef MethodDef +#define MethodDef(func) _MethodDef(func, Scene) + +/* these are the scene object methods */ +static struct PyMethodDef Scene_methods[] = { + MethodDef(copy), + MethodDef(link), + MethodDef(unlink), + MethodDef(getChildren), + MethodDef(getCurrentCamera), + MethodDef(setCurrentCamera), + MethodDef(getRenderdir), + MethodDef(getBackbufdir), + MethodDef(frameSettings), + MethodDef(makeCurrent), + MethodDef(update), + {NULL, NULL} +}; + +static void PyScene_dealloc(PyObject *self) +{ + PyMem_DEL(self); +} + +static PyObject *PyScene_getattr(PyObject *self, char *attr) +{ + Scene *scene; + if (!strcmp(attr, "name")) { + return PyString_FromString(((PyScene *) self)->name); + } else if (!strcmp(attr, "users")) { + scene = PyScene_AsScene(self); + return PyInt_FromLong(getUsers(scene)); + } else if (!strcmp(attr, "block_type")) { + return Py_BuildValue("s", "Scene"); + } + return Py_FindMethod(Scene_methods, (PyObject *) self, attr); +} + +PyObject *PyScene_repr(PyScene *self) +{ + char s[256]; + Scene *scene = PyScene_AsScene(self); + if (scene) + sprintf (s, "[Scene %.32s]", getName(scene)); + else + sprintf (s, "[deleted Scene]"); + return Py_BuildValue("s", s); +} + +static PyTypeObject PyScene_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Scene", /*tp_name*/ + sizeof(PyScene), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) PyScene_dealloc, /*tp_dealloc*/ + (printfunc)0, /*tp_print*/ + (getattrfunc)PyScene_getattr, /*tp_getattr*/ + (setattrfunc)0, /*tp_setattr*/ + (cmpfunc)0, /*tp_compare*/ + (reprfunc)PyScene_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + (hashfunc)0, /*tp_hash*/ + (ternaryfunc)0, /*tp_call*/ + (reprfunc)0, /*tp_str*/ + + /* Space for future expansion */ + 0L,0L,0L,0L, + 0 /* Documentation string */ +}; + +static PyObject *newPyScene(char *name) +{ + PyScene *scene = PyObject_NEW(PyScene, &PyScene_Type); + strncpy(scene->name, name, 31); + return (PyObject *) scene; +} + +PyObject *PyScene_FromScene(Scene *scene) +{ + if (scene) + return newPyScene(getName(scene)); + else { + Py_INCREF(Py_None); + return Py_None; + } +} + +PyObject *PyScene_FromVoid(void *scene) +{ + return PyScene_FromScene((Scene *) scene); +} + + +/************************/ +/* Scene module methods */ + +static char Scenemodule_get_doc[] = +"(name = None) - get Scene 'name' from Blender, if 'name' specified.\n\ +Otherwise, a list of all Scenes is returned"; + +static PyObject *Scenemodule_get(PyObject *self, PyObject *args) +{ + char *name= NULL; + BPY_TRY(PyArg_ParseTuple(args, "|s", &name)); + + if (name) { + return PyScene_FromScene(getSceneByName(name)); + } else { + return BPY_PyList_FromIDList(getSceneList(), PyScene_FromVoid); + } +} + +static char Scenemodule_New_doc[] = +"(name = None) - Create new scene with (optionally given)\n\ +name."; + +static PyObject *Scenemodule_New(PyObject *self, PyObject *args) +{ + Scene *scene; + char *name = "Scene"; + + BPY_TRY(PyArg_ParseTuple(args, "|s", &name)); + scene = add_scene(name); + return newPyScene(name); +} + +static char Scenemodule_getCurrent_doc[] = +"() - returns currently active Scene"; + +static PyObject *Scenemodule_getCurrent(PyObject *self, PyObject *args) +{ + return newPyScene(getName(scene_getCurrent())); +} + +static char Scenemodule_unlink_doc[] = +"(scene) - deletes the Scene 'scene' from Blender\n\ +The Scene must be empty before removing it"; + +static PyObject *Scenemodule_unlink(PyObject *self, PyObject *args) +{ + PyObject *sceneobj; + Scene *scene; + + if(!PyArg_ParseTuple(args, "O!", &PyScene_Type, &sceneobj)) { + PyErr_SetString(PyExc_TypeError, "Scene object expected!"); + return NULL; + } + + scene = PyScene_AsScene(sceneobj); + free_libblock(getSceneList(), scene); + Py_INCREF(Py_None); + return Py_None; +} + + +/*****************/ +/* METHOD TABLES */ + +/* these are the module methods */ + +#undef MethodDef +#define MethodDef(func) _MethodDef(func, Scenemodule) + +struct PyMethodDef Scenemodule_methods[] = { + MethodDef(get), + MethodDef(getCurrent), + MethodDef(New), + MethodDef(unlink), + {NULL, NULL} +}; + +PyObject *initScene() +{ + PyObject *mod; + PyScene_Type.ob_type = &PyType_Type; + mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Scene", + Scenemodule_methods); + return mod; +} + + |