* Applied a small fix to a bug reported by Guignot:

When a script that used setAttr for Camera Data objs (the bug also
    affected some other modules) was executed multiple times, Blender
    would crash after, let's say, the first 5 or 6 tries.  Problem, as
    Guignot pointed, was with reference counting.  Should be ok now, all
    affected modules were fixed.
* The Scene module is now "complete" (= 2.25).
* Made some necessary updates to Object and NMesh.
This commit is contained in:
2003-06-09 04:01:48 +00:00
parent 51850586a8
commit 864e5640f7
15 changed files with 723 additions and 225 deletions

View File

@@ -290,7 +290,7 @@ static int ArmatureSetAttr (C_Armature *self, char *name, PyObject *value)
PyObject *valtuple; PyObject *valtuple;
PyObject *error = NULL; PyObject *error = NULL;
valtuple = Py_BuildValue("(N)", value); /*the set* functions expect a tuple*/ valtuple = Py_BuildValue("(O)", value); /*the set* functions expect a tuple*/
if (!valtuple) if (!valtuple)
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -625,7 +625,7 @@ static int BoneSetAttr (C_Bone *self, char *name, PyObject *value)
PyObject *valtuple; PyObject *valtuple;
PyObject *error = NULL; PyObject *error = NULL;
valtuple = Py_BuildValue("(N)", value); /* the set* functions expect a tuple */ valtuple = Py_BuildValue("(O)", value); /* the set* functions expect a tuple */
if (!valtuple) if (!valtuple)
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -38,7 +38,8 @@
* given, all preceding ones must be given, too. Of course, this only relates * given, all preceding ones must be given, too. Of course, this only relates
* to the Python functions and methods described here and only inside Python * to the Python functions and methods described here and only inside Python
* code. [ This will go to another file later, probably the main exppython * code. [ This will go to another file later, probably the main exppython
* doc file]. * doc file]. XXX Better: put optional args with their default value:
* (self, name = "MyName")
*/ */
#include <BKE_main.h> #include <BKE_main.h>
@@ -257,6 +258,10 @@ static PyObject *M_Camera_New(PyObject *self, PyObject *args, PyObject *kwords)
return (EXPP_ReturnPyObjError (PyExc_RuntimeError, return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't create Camera Data in Blender")); "couldn't create Camera Data in Blender"));
/* let's return user count to zero, because ... */
blcam->id.us = 0; /* ... add_camera() right above incref'ed it */
/* XXX XXX Do this in other modules, too */
if (pycam == NULL) if (pycam == NULL)
return (EXPP_ReturnPyObjError (PyExc_MemoryError, return (EXPP_ReturnPyObjError (PyExc_MemoryError,
"couldn't create Camera Data object")); "couldn't create Camera Data object"));
@@ -876,8 +881,8 @@ static int Camera_SetAttr (BPy_Camera *self, char *name, PyObject *value)
* interval and updates the Blender Camera structure when necessary. */ * interval and updates the Blender Camera structure when necessary. */
/* First we put "value" in a tuple, because we want to pass it to functions /* First we put "value" in a tuple, because we want to pass it to functions
* that only accept PyTuples. Using "N" doesn't increment value's ref count */ * that only accept PyTuples. */
valtuple = Py_BuildValue("(N)", value); valtuple = Py_BuildValue("(O)", value);
if (!valtuple) /* everything OK with our PyObject? */ if (!valtuple) /* everything OK with our PyObject? */
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -51,6 +51,7 @@ PyTypeObject Camera_Type;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
Camera *camera; Camera *camera;
} BPy_Camera; } BPy_Camera;
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -614,7 +614,7 @@ static PyObject *CurveGetAttr (C_Curve *self, char *name)//getattr
static int CurveSetAttr (C_Curve *self, char *name, PyObject *value) static int CurveSetAttr (C_Curve *self, char *name, PyObject *value)
{ PyObject *valtuple; { PyObject *valtuple;
PyObject *error = NULL; PyObject *error = NULL;
valtuple = Py_BuildValue("(N)", value); valtuple = Py_BuildValue("(O)", value);
//resolu resolv width ext1 ext2 //resolu resolv width ext1 ext2
if (!valtuple) if (!valtuple)
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -451,7 +451,7 @@ static int Image_SetAttr (C_Image *self, char *name, PyObject *value)
* function anyway, since it already has error checking, clamps to the right * function anyway, since it already has error checking, clamps to the right
* interval and updates the Blender Image structure when necessary. */ * interval and updates the Blender Image structure when necessary. */
valtuple = Py_BuildValue("(N)", value); /*the set* functions expect a tuple*/ valtuple = Py_BuildValue("(O)", value); /*the set* functions expect a tuple*/
if (!valtuple) if (!valtuple)
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -912,7 +912,7 @@ static int LampSetAttr (C_Lamp *self, char *name, PyObject *value)
PyObject *valtuple; PyObject *valtuple;
PyObject *error = NULL; PyObject *error = NULL;
valtuple = Py_BuildValue("(N)", value); /* the set* functions expect a tuple */ valtuple = Py_BuildValue("(O)", value); /* the set* functions expect a tuple */
if (!valtuple) if (!valtuple)
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -1254,8 +1254,8 @@ static int Material_SetAttr (C_Material *self, char *name, PyObject *value)
* interval and updates the Blender Material structure when necessary. */ * interval and updates the Blender Material structure when necessary. */
/* First we put "value" in a tuple, because we want to pass it to functions /* First we put "value" in a tuple, because we want to pass it to functions
* that only accept PyTuples. Using "N" doesn't increment value's ref count */ * that only accept PyTuples. */
valtuple = Py_BuildValue("(N)", value); valtuple = Py_BuildValue("(O)", value);
if (!valtuple) /* everything OK with our PyObject? */ if (!valtuple) /* everything OK with our PyObject? */
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -1008,7 +1008,7 @@ if (strcmp (name, "rot") == 0)return Metaball_getrot (self);
/*******************************************************************************/ /*******************************************************************************/
static int MetaballSetAttr (C_Metaball *self, char *name, PyObject *value) static int MetaballSetAttr (C_Metaball *self, char *name, PyObject *value)
{ {
PyObject *valtuple = Py_BuildValue("(N)", value); PyObject *valtuple = Py_BuildValue("(O)", value);
if (!valtuple) if (!valtuple)
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -761,7 +761,7 @@ PyObject *NMesh_link(PyObject *self, PyObject *args)
{/* {/*
C_Object *bl_obj; C_Object *bl_obj;
if (!PyArg_ParseTuple(args, "O!", &Object_Type, bl_obj)) if (!PyArg_ParseTuple(args, "O!", &Object_Type, &bl_obj))
return EXPP_ReturnPyErrorObj (PyExc_TypeError, return EXPP_ReturnPyErrorObj (PyExc_TypeError,
"NMesh can only be linked to Objects"); "NMesh can only be linked to Objects");
@@ -1682,3 +1682,20 @@ PyObject *M_NMesh_Init (void)
g_nmeshmodule = submodule; g_nmeshmodule = submodule;
return submodule; return submodule;
} }
/* These are needed by Object.c */
PyObject *NMesh_CreatePyObject (Mesh *me)
{
return new_NMesh (me);
}
int NMesh_CheckPyObject (PyObject *pyobj)
{
return (pyobj->ob_type == &NMesh_Type);
}
Mesh *NMesh_FromPyObject (PyObject *pyobj)
{
return ((C_NMesh *)pyobj)->mesh;
}

View File

@@ -31,11 +31,196 @@
#include "Object.h" #include "Object.h"
/*****************************************************************************/
/* Python API function prototypes for the Blender module. */
/*****************************************************************************/
static PyObject *M_Object_New(PyObject *self, PyObject *args);
PyObject *M_Object_Get(PyObject *self, PyObject *args);
static PyObject *M_Object_GetSelected (PyObject *self, PyObject *args);
/*****************************************************************************/
/* The following string definitions are used for documentation strings. */
/* In Python these will be written to the console when doing a */
/* Blender.Object.__doc__ */
/*****************************************************************************/
char M_Object_doc[] =
"The Blender Object module\n\n\
This module provides access to **Object Data** in Blender.\n";
char M_Object_New_doc[] =
"(type) - Add a new object of type 'type' in the current scene";
char M_Object_Get_doc[] =
"(name) - return the object with the name 'name', returns None if not\
found.\n\
If 'name' is not specified, it returns a list of all objects in the\n\
current scene.";
char M_Object_GetSelected_doc[] =
"() - Returns a list of selected Objects in the active layer(s)\n\
The active object is the first in the list, if visible";
/*****************************************************************************/
/* Python method structure definition for Blender.Object module: */
/*****************************************************************************/
struct PyMethodDef M_Object_methods[] = {
{"New", (PyCFunction)M_Object_New, METH_VARARGS,
M_Object_New_doc},
{"Get", (PyCFunction)M_Object_Get, METH_VARARGS,
M_Object_Get_doc},
{"get", (PyCFunction)M_Object_Get, METH_VARARGS,
M_Object_Get_doc},
{"getSelected", (PyCFunction)M_Object_GetSelected, METH_VARARGS,
M_Object_GetSelected_doc},
{NULL, NULL, 0, NULL}
};
/*****************************************************************************/
/* Python C_Object methods declarations: */
/*****************************************************************************/
static PyObject *Object_clrParent (C_Object *self, PyObject *args);
static PyObject *Object_getData (C_Object *self);
static PyObject *Object_getDeformData (C_Object *self);
static PyObject *Object_getDeltaLocation (C_Object *self);
static PyObject *Object_getDrawMode (C_Object *self);
static PyObject *Object_getDrawType (C_Object *self);
static PyObject *Object_getEuler (C_Object *self);
static PyObject *Object_getInverseMatrix (C_Object *self);
static PyObject *Object_getLocation (C_Object *self, PyObject *args);
static PyObject *Object_getMaterials (C_Object *self);
static PyObject *Object_getMatrix (C_Object *self);
static PyObject *Object_getParent (C_Object *self);
static PyObject *Object_getTracked (C_Object *self);
static PyObject *Object_getType (C_Object *self);
static PyObject *Object_link (C_Object *self, PyObject *args);
static PyObject *Object_makeParent (C_Object *self, PyObject *args);
static PyObject *Object_materialUsage (C_Object *self, PyObject *args);
static PyObject *Object_setDeltaLocation (C_Object *self, PyObject *args);
static PyObject *Object_setDrawMode (C_Object *self, PyObject *args);
static PyObject *Object_setDrawType (C_Object *self, PyObject *args);
static PyObject *Object_setEuler (C_Object *self, PyObject *args);
static PyObject *Object_setLocation (C_Object *self, PyObject *args);
static PyObject *Object_setMaterials (C_Object *self, PyObject *args);
static PyObject *Object_shareFrom (C_Object *self, PyObject *args);
/*****************************************************************************/
/* Python C_Object methods table: */
/*****************************************************************************/
static PyMethodDef C_Object_methods[] = {
/* name, method, flags, doc */
{"clrParent", (PyCFunction)Object_clrParent, METH_VARARGS,
"Clears parent object. Optionally specify:\n\
mode\n\t2: Keep object transform\nfast\n\t>0: Don't update scene \
hierarchy (faster)"},
{"getData", (PyCFunction)Object_getData, METH_NOARGS,
"Returns the datablock object containing the object's data, \
e.g. Mesh"},
{"getDeformData", (PyCFunction)Object_getDeformData, METH_NOARGS,
"Returns the datablock object containing the object's deformed \
data.\nCurrently, this is only supported for a Mesh"},
{"getDeltaLocation", (PyCFunction)Object_getDeltaLocation, METH_NOARGS,
"Returns the object's delta location (x, y, z)"},
{"getDrawMode", (PyCFunction)Object_getDrawMode, METH_NOARGS,
"Returns the object draw modes"},
{"getDrawType", (PyCFunction)Object_getDrawType, METH_NOARGS,
"Returns the object draw type"},
{"getEuler", (PyCFunction)Object_getEuler, METH_NOARGS,
"Returns the object's rotation as Euler rotation vector\n\
(rotX, rotY, rotZ)"},
{"getInverseMatrix", (PyCFunction)Object_getInverseMatrix, METH_NOARGS,
"Returns the object's inverse matrix"},
{"getLocation", (PyCFunction)Object_getLocation, METH_VARARGS,
"Returns the object's location (x, y, z)"},
{"getMaterials", (PyCFunction)Object_getMaterials, METH_NOARGS,
"Returns list of materials assigned to the object"},
{"getMatrix", (PyCFunction)Object_getMatrix, METH_NOARGS,
"Returns the object matrix"},
{"getParent", (PyCFunction)Object_getParent, METH_NOARGS,
"Returns the object's parent object"},
{"getTracked", (PyCFunction)Object_getTracked, METH_NOARGS,
"Returns the object's tracked object"},
{"getType", (PyCFunction)Object_getType, METH_NOARGS,
"Returns type of string of Object"},
{"link", (PyCFunction)Object_link, METH_VARARGS,
"Links Object with data provided in the argument. The data must \n\
match the Object's type, so you cannot link a Lamp to a Mesh type object."},
{"makeParent", (PyCFunction)Object_makeParent, METH_VARARGS,
"Makes the object the parent of the objects provided in the \n\
argument which must be a list of valid Objects. Optional extra arguments:\n\
mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
fase:\n\t0: update scene hierarchy automatically\n\t\
don't update scene hierarchy (faster). In this case, you must\n\t\
explicitely update the Scene hierarchy."},
{"materialUsage", (PyCFunction)Object_materialUsage, METH_VARARGS,
"Determines the way the material is used and returs status.\n\
Possible arguments (provide as strings):\n\
\tData: Materials assigned to the object's data are shown. (default)\n\
\tObject: Materials assigned to the object are shown."},
{"setDeltaLocation", (PyCFunction)Object_setDeltaLocation, METH_VARARGS,
"Sets the object's delta location which must be a vector triple."},
{"setDrawMode", (PyCFunction)Object_setDrawMode, METH_VARARGS,
"Sets the object's drawing mode. The argument can be a sum of:\n\
2: axis\n4: texspace\n8: drawname\n16: drawimage\n32: drawwire"},
{"setDrawType", (PyCFunction)Object_setDrawType, METH_VARARGS,
"Sets the object's drawing type. The argument must be one of:\n\
1: Bounding box\n2: Wire\n3: Solid\n4: Shaded\n5: Textured"},
{"setEuler", (PyCFunction)Object_setEuler, METH_VARARGS,
"Set the object's rotation according to the specified Euler\n\
angles. The argument must be a vector triple"},
{"setLocation", (PyCFunction)Object_setLocation, METH_VARARGS,
"Set the object's location. The first argument must be a vector\n\
triple."},
{"setMaterials", (PyCFunction)Object_setMaterials, METH_VARARGS,
"Sets materials. The argument must be a list of valid material\n\
objects."},
{"shareFrom", (PyCFunction)Object_shareFrom, METH_VARARGS,
"Link data of self with object specified in the argument. This\n\
works only if self and the object specified are of the same type."},
{0}
};
/*****************************************************************************/
/* PythonTypeObject callback function prototypes */
/*****************************************************************************/
static void ObjectDeAlloc (C_Object *obj);
static int ObjectPrint (C_Object *obj, FILE *fp, int flags);
static PyObject* ObjectGetAttr (C_Object *obj, char *name);
static int ObjectSetAttr (C_Object *obj, char *name, PyObject *v);
static PyObject* ObjectRepr (C_Object *obj);
/*****************************************************************************/
/* Python TypeObject structure definition. */
/*****************************************************************************/
PyTypeObject Object_Type =
{
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"Object", /* tp_name */
sizeof (C_Object), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)ObjectDeAlloc, /* tp_dealloc */
(printfunc)ObjectPrint, /* tp_print */
(getattrfunc)ObjectGetAttr, /* tp_getattr */
(setattrfunc)ObjectSetAttr, /* tp_setattr */
0, /* tp_compare */
(reprfunc)ObjectRepr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_as_hash */
0,0,0,0,0,0,
0, /* tp_doc */
0,0,0,0,0,0,
C_Object_methods, /* tp_methods */
0, /* tp_members */
};
/*****************************************************************************/ /*****************************************************************************/
/* Function: M_Object_New */ /* Function: M_Object_New */
/* Python equivalent: Blender.Object.New */ /* Python equivalent: Blender.Object.New */
/*****************************************************************************/ /*****************************************************************************/
static PyObject *M_Object_New(PyObject *self, PyObject *args) PyObject *M_Object_New(PyObject *self, PyObject *args)
{ {
struct Object * object; struct Object * object;
C_Object * blen_object; C_Object * blen_object;
@@ -192,7 +377,7 @@ static PyObject *M_Object_New(PyObject *self, PyObject *args)
/* Function: M_Object_Get */ /* Function: M_Object_Get */
/* Python equivalent: Blender.Object.Get */ /* Python equivalent: Blender.Object.Get */
/*****************************************************************************/ /*****************************************************************************/
static PyObject *M_Object_Get(PyObject *self, PyObject *args) PyObject *M_Object_Get(PyObject *self, PyObject *args)
{ {
struct Object * object; struct Object * object;
char * name = NULL; char * name = NULL;
@@ -358,8 +543,8 @@ static PyObject *Object_clrParent (C_Object *self, PyObject *args)
static PyObject *Object_getData (C_Object *self) static PyObject *Object_getData (C_Object *self)
{ {
PyObject * data_object; PyObject * data_object;
int obj_id; //# int obj_id;
ID * id; //# ID * id;
/* If there's a valid PyObject already, then just return that one. */ /* If there's a valid PyObject already, then just return that one. */
if (self->data != NULL) if (self->data != NULL)
@@ -378,14 +563,14 @@ static PyObject *Object_getData (C_Object *self)
data_object = NULL; data_object = NULL;
id = (ID*)self->object; //#id = (ID*)self->object;
obj_id = MAKE_ID2 (id->name[0], id->name[1]); //#obj_id = MAKE_ID2 (id->name[0], id->name[1]);
switch (obj_id) switch (self->object->type)//#obj_id)
{ {
case ID_AR: case ID_AR:
data_object = M_ArmatureCreatePyObject (self->object->data); data_object = M_ArmatureCreatePyObject (self->object->data);
break; break;
case ID_CA: case OB_CAMERA://#ID_CA:
data_object = Camera_CreatePyObject (self->object->data); data_object = Camera_CreatePyObject (self->object->data);
break; break;
case ID_CU: case ID_CU:

View File

@@ -34,7 +34,6 @@
#include <Python.h> #include <Python.h>
#include <stdio.h> #include <stdio.h>
#include <BDR_editobject.h> #include <BDR_editobject.h>
#include <BKE_armature.h> #include <BKE_armature.h>
#include <BKE_curve.h> #include <BKE_curve.h>
@@ -50,7 +49,6 @@
#include <DNA_ID.h> #include <DNA_ID.h>
#include <DNA_ika_types.h> #include <DNA_ika_types.h>
#include <DNA_listBase.h> #include <DNA_listBase.h>
#include <DNA_object_types.h>
#include <DNA_scene_types.h> #include <DNA_scene_types.h>
#include <DNA_userdef_types.h> #include <DNA_userdef_types.h>
#include <DNA_view3d_types.h> #include <DNA_view3d_types.h>
@@ -58,34 +56,11 @@
#include "gen_utils.h" #include "gen_utils.h"
#include "modules.h" #include "modules.h"
/*****************************************************************************/ /* The Object PyType Object defined in Object.c */
/* Python API function prototypes for the Blender module. */ PyTypeObject Object_Type;
/*****************************************************************************/
static PyObject *M_Object_New(PyObject *self, PyObject *args);
static PyObject *M_Object_Get(PyObject *self, PyObject *args);
static PyObject *M_Object_GetSelected (PyObject *self, PyObject *args);
/*****************************************************************************/ #define C_Object_Check(v) \
/* The following string definitions are used for documentation strings. */ ((v)->ob_type == &Object_Type) /* for type checking */
/* In Python these will be written to the console when doing a */
/* Blender.Object.__doc__ */
/*****************************************************************************/
char M_Object_doc[] =
"The Blender Object module\n\n\
This module provides access to **Object Data** in Blender.\n";
char M_Object_New_doc[] =
"(type) - Add a new object of type 'type' in the current scene";
char M_Object_Get_doc[] =
"(name) - return the object with the name 'name', returns None if not\
found.\n\
If 'name' is not specified, it returns a list of all objects in the\n\
current scene.";
char M_Object_GetSelected_doc[] =
"() - Returns a list of selected Objects in the active layer(s)\n\
The active object is the first in the list, if visible";
/*****************************************************************************/ /*****************************************************************************/
/* Python C_Object structure definition. */ /* Python C_Object structure definition. */
@@ -109,160 +84,4 @@ typedef struct {
struct C_Object * track; struct C_Object * track;
} C_Object; } C_Object;
/*****************************************************************************/
/* Python method structure definition for Blender.Object module: */
/*****************************************************************************/
struct PyMethodDef M_Object_methods[] = {
{"New", (PyCFunction)M_Object_New, METH_VARARGS,
M_Object_New_doc},
{"Get", (PyCFunction)M_Object_Get, METH_VARARGS,
M_Object_Get_doc},
{"get", (PyCFunction)M_Object_Get, METH_VARARGS,
M_Object_Get_doc},
{"getSelected", (PyCFunction)M_Object_GetSelected, METH_VARARGS,
M_Object_GetSelected_doc},
{NULL, NULL, 0, NULL}
};
/*****************************************************************************/
/* Python C_Object methods declarations: */
/*****************************************************************************/
static PyObject *Object_clrParent (C_Object *self, PyObject *args);
static PyObject *Object_getData (C_Object *self);
static PyObject *Object_getDeformData (C_Object *self);
static PyObject *Object_getDeltaLocation (C_Object *self);
static PyObject *Object_getDrawMode (C_Object *self);
static PyObject *Object_getDrawType (C_Object *self);
static PyObject *Object_getEuler (C_Object *self);
static PyObject *Object_getInverseMatrix (C_Object *self);
static PyObject *Object_getLocation (C_Object *self, PyObject *args);
static PyObject *Object_getMaterials (C_Object *self);
static PyObject *Object_getMatrix (C_Object *self);
static PyObject *Object_getParent (C_Object *self);
static PyObject *Object_getTracked (C_Object *self);
static PyObject *Object_getType (C_Object *self);
static PyObject *Object_link (C_Object *self, PyObject *args);
static PyObject *Object_makeParent (C_Object *self, PyObject *args);
static PyObject *Object_materialUsage (C_Object *self, PyObject *args);
static PyObject *Object_setDeltaLocation (C_Object *self, PyObject *args);
static PyObject *Object_setDrawMode (C_Object *self, PyObject *args);
static PyObject *Object_setDrawType (C_Object *self, PyObject *args);
static PyObject *Object_setEuler (C_Object *self, PyObject *args);
static PyObject *Object_setLocation (C_Object *self, PyObject *args);
static PyObject *Object_setMaterials (C_Object *self, PyObject *args);
static PyObject *Object_shareFrom (C_Object *self, PyObject *args);
/*****************************************************************************/
/* Python C_Object methods table: */
/*****************************************************************************/
static PyMethodDef C_Object_methods[] = {
/* name, method, flags, doc */
{"clrParent", (PyCFunction)Object_clrParent, METH_VARARGS,
"Clears parent object. Optionally specify:\n\
mode\n\t2: Keep object transform\nfast\n\t>0: Don't update scene \
hierarchy (faster)"},
{"getData", (PyCFunction)Object_getData, METH_NOARGS,
"Returns the datablock object containing the object's data, \
e.g. Mesh"},
{"getDeformData", (PyCFunction)Object_getDeformData, METH_NOARGS,
"Returns the datablock object containing the object's deformed \
data.\nCurrently, this is only supported for a Mesh"},
{"getDeltaLocation", (PyCFunction)Object_getDeltaLocation, METH_NOARGS,
"Returns the object's delta location (x, y, z)"},
{"getDrawMode", (PyCFunction)Object_getDrawMode, METH_NOARGS,
"Returns the object draw modes"},
{"getDrawType", (PyCFunction)Object_getDrawType, METH_NOARGS,
"Returns the object draw type"},
{"getEuler", (PyCFunction)Object_getEuler, METH_NOARGS,
"Returns the object's rotation as Euler rotation vector\n\
(rotX, rotY, rotZ)"},
{"getInverseMatrix", (PyCFunction)Object_getInverseMatrix, METH_NOARGS,
"Returns the object's inverse matrix"},
{"getLocation", (PyCFunction)Object_getLocation, METH_VARARGS,
"Returns the object's location (x, y, z)"},
{"getMaterials", (PyCFunction)Object_getMaterials, METH_NOARGS,
"Returns list of materials assigned to the object"},
{"getMatrix", (PyCFunction)Object_getMatrix, METH_NOARGS,
"Returns the object matrix"},
{"getParent", (PyCFunction)Object_getParent, METH_NOARGS,
"Returns the object's parent object"},
{"getTracked", (PyCFunction)Object_getTracked, METH_NOARGS,
"Returns the object's tracked object"},
{"getType", (PyCFunction)Object_getType, METH_NOARGS,
"Returns type of string of Object"},
{"link", (PyCFunction)Object_link, METH_VARARGS,
"Links Object with data provided in the argument. The data must \n\
match the Object's type, so you cannot link a Lamp to a Mesh type object."},
{"makeParent", (PyCFunction)Object_makeParent, METH_VARARGS,
"Makes the object the parent of the objects provided in the \n\
argument which must be a list of valid Objects. Optional extra arguments:\n\
mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
fase:\n\t0: update scene hierarchy automatically\n\t\
don't update scene hierarchy (faster). In this case, you must\n\t\
explicitely update the Scene hierarchy."},
{"materialUsage", (PyCFunction)Object_materialUsage, METH_VARARGS,
"Determines the way the material is used and returs status.\n\
Possible arguments (provide as strings):\n\
\tData: Materials assigned to the object's data are shown. (default)\n\
\tObject: Materials assigned to the object are shown."},
{"setDeltaLocation", (PyCFunction)Object_setDeltaLocation, METH_VARARGS,
"Sets the object's delta location which must be a vector triple."},
{"setDrawMode", (PyCFunction)Object_setDrawMode, METH_VARARGS,
"Sets the object's drawing mode. The argument can be a sum of:\n\
2: axis\n4: texspace\n8: drawname\n16: drawimage\n32: drawwire"},
{"setDrawType", (PyCFunction)Object_setDrawType, METH_VARARGS,
"Sets the object's drawing type. The argument must be one of:\n\
1: Bounding box\n2: Wire\n3: Solid\n4: Shaded\n5: Textured"},
{"setEuler", (PyCFunction)Object_setEuler, METH_VARARGS,
"Set the object's rotation according to the specified Euler\n\
angles. The argument must be a vector triple"},
{"setLocation", (PyCFunction)Object_setLocation, METH_VARARGS,
"Set the object's location. The first argument must be a vector\n\
triple."},
{"setMaterials", (PyCFunction)Object_setMaterials, METH_VARARGS,
"Sets materials. The argument must be a list of valid material\n\
objects."},
{"shareFrom", (PyCFunction)Object_shareFrom, METH_VARARGS,
"Link data of self with object specified in the argument. This\n\
works only if self and the object specified are of the same type."},
{0}
};
/*****************************************************************************/
/* PythonTypeObject callback function prototypes */
/*****************************************************************************/
static void ObjectDeAlloc (C_Object *obj);
static int ObjectPrint (C_Object *obj, FILE *fp, int flags);
static PyObject* ObjectGetAttr (C_Object *obj, char *name);
static int ObjectSetAttr (C_Object *obj, char *name, PyObject *v);
static PyObject* ObjectRepr (C_Object *obj);
/*****************************************************************************/
/* Python TypeObject structure definition. */
/*****************************************************************************/
PyTypeObject Object_Type =
{
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"Object", /* tp_name */
sizeof (C_Object), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)ObjectDeAlloc, /* tp_dealloc */
(printfunc)ObjectPrint, /* tp_print */
(getattrfunc)ObjectGetAttr, /* tp_getattr */
(setattrfunc)ObjectSetAttr, /* tp_setattr */
0, /* tp_compare */
(reprfunc)ObjectRepr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_as_hash */
0,0,0,0,0,0,
0, /* tp_doc */
0,0,0,0,0,0,
C_Object_methods, /* tp_methods */
0, /* tp_members */
};
#endif /* EXPP_OBJECT_H */ #endif /* EXPP_OBJECT_H */

View File

@@ -33,12 +33,6 @@
* \file Scene.c * \file Scene.c
* \ingroup scripts * \ingroup scripts
* \brief Blender.Scene Module and Scene PyObject implementation. * \brief Blender.Scene Module and Scene PyObject implementation.
*
* Note: Parameters between "<" and ">" are optional. But if one of them is
* given, all preceding ones must be given, too. Of course, this only relates
* to the Python functions and methods described here and only inside Python
* code. [ This will go to another file later, probably the main exppython
* doc file].
*/ */
#include <BKE_main.h> #include <BKE_main.h>
@@ -46,12 +40,25 @@
#include <BKE_scene.h> #include <BKE_scene.h>
#include <BKE_library.h> #include <BKE_library.h>
#include <BLI_blenlib.h> #include <BLI_blenlib.h>
#include <BSE_headerbuttons.h> /* for copy_scene */
#include <BIF_drawscene.h> /* for set_scene */
#include <BIF_space.h> /* for copy_view3d_lock() */
#include <MEM_guardedalloc.h> /* for MEM_callocN */
#include <mydevice.h> /* for #define REDRAW */
#include "Object.h"
#include "Camera.h"
#include "modules.h"
#include "Scene.h" #include "Scene.h"
static Base *EXPP_Scene_getObjectBase (Scene *scene, Object *object);
PyObject *M_Object_Get (PyObject *self, PyObject *args); /* from Object.c */
/*****************************************************************************/ /*****************************************************************************/
/* Python BPy_Scene defaults: */ /* Python BPy_Scene defaults: */
/*****************************************************************************/ /*****************************************************************************/
#define EXPP_SCENE_FRAME_MAX 18000
/*****************************************************************************/ /*****************************************************************************/
/* Python API function prototypes for the Scene module. */ /* Python API function prototypes for the Scene module. */
@@ -95,7 +102,21 @@ struct PyMethodDef M_Scene_methods[] = {
/* Python BPy_Scene methods declarations: */ /* Python BPy_Scene methods declarations: */
/*****************************************************************************/ /*****************************************************************************/
static PyObject *Scene_getName(BPy_Scene *self); static PyObject *Scene_getName(BPy_Scene *self);
static PyObject *Scene_setName(BPy_Scene *self, PyObject *args); static PyObject *Scene_setName(BPy_Scene *self, PyObject *arg);
static PyObject *Scene_copy(BPy_Scene *self, PyObject *arg);
static PyObject *Scene_startFrame(BPy_Scene *self, PyObject *args);
static PyObject *Scene_endFrame(BPy_Scene *self, PyObject *args);
static PyObject *Scene_currentFrame(BPy_Scene *self, PyObject *args);
static PyObject *Scene_frameSettings (BPy_Scene *self, PyObject *args);
static PyObject *Scene_makeCurrent(BPy_Scene *self);
static PyObject *Scene_update(BPy_Scene *self);
static PyObject *Scene_link(BPy_Scene *self, PyObject *args);
static PyObject *Scene_unlink(BPy_Scene *self, PyObject *args);
static PyObject *Scene_getRenderdir(BPy_Scene *self);
static PyObject *Scene_getBackbufdir(BPy_Scene *self);
static PyObject *Scene_getChildren(BPy_Scene *self);
static PyObject *Scene_getCurrentCamera(BPy_Scene *self);
static PyObject *Scene_setCurrentCamera(BPy_Scene *self, PyObject *args);
/*****************************************************************************/ /*****************************************************************************/
/* Python BPy_Scene methods table: */ /* Python BPy_Scene methods table: */
@@ -106,6 +127,42 @@ static PyMethodDef BPy_Scene_methods[] = {
"() - Return Scene name"}, "() - Return Scene name"},
{"setName", (PyCFunction)Scene_setName, METH_VARARGS, {"setName", (PyCFunction)Scene_setName, METH_VARARGS,
"(str) - Change Scene name"}, "(str) - Change Scene name"},
{"copy", (PyCFunction)Scene_copy, METH_VARARGS,
"(duplicate_objects = 1) - Return a copy of this scene\n"
"The optional argument duplicate_objects defines how the scene\n"
"children are duplicated:\n\t0: Link Objects\n\t1: Link Object Data"
"\n\t2: Full copy\n"},
{"startFrame", (PyCFunction)Scene_startFrame, METH_VARARGS,
"(frame) - If frame is given, the start frame is set and"
"\nreturned in any case"},
{"endFrame", (PyCFunction)Scene_endFrame, METH_VARARGS,
"(frame) - If frame is given, the end frame is set and"
"\nreturned in any case"},
{"currentFrame", (PyCFunction)Scene_currentFrame, METH_VARARGS,
"(frame) - If frame is given, the current frame is set and"
"\nreturned in any case"},
{"frameSettings", (PyCFunction)Scene_frameSettings, METH_NOARGS,
"(start, end, current) - Sets or retrieves the Scene's frame"
" settings.\nIf the frame arguments are specified, they are set. "
"A tuple (start, end, current) is returned in any case."},
{"makeCurrent", (PyCFunction)Scene_makeCurrent, METH_NOARGS,
"() - Make self the current scene"},
{"update", (PyCFunction)Scene_update, METH_NOARGS,
"() - Update scene self"},
{"link", (PyCFunction)Scene_link, METH_VARARGS,
"(obj) - Link Object obj to this scene"},
{"unlink", (PyCFunction)Scene_unlink, METH_VARARGS,
"(obj) - Unlink Object obj from this scene"},
{"getRenderdir", (PyCFunction)Scene_getRenderdir, METH_NOARGS,
"() - Return directory where rendered images are saved to"},
{"getBackbufdir", (PyCFunction)Scene_getBackbufdir, METH_NOARGS,
"() - Return location of the backbuffer image"},
{"getChildren", (PyCFunction)Scene_getChildren, METH_NOARGS,
"() - Return list of all objects linked to scene self"},
{"getCurrentCamera", (PyCFunction)Scene_getCurrentCamera, METH_NOARGS,
"() - Return current active Camera"},
{"setCurrentCamera", (PyCFunction)Scene_setCurrentCamera, METH_VARARGS,
"() - Set the currently active Camera"},
{0} {0}
}; };
@@ -271,7 +328,7 @@ static PyObject *M_Scene_Get(PyObject *self, PyObject *args)
* \return A Python wrapper for the currently active scene. * \return A Python wrapper for the currently active scene.
*/ */
PyObject *M_Scene_getCurrent (PyObject *self) static PyObject *M_Scene_getCurrent (PyObject *self)
{ {
return Scene_CreatePyObject ((Scene *)G.scene); return Scene_CreatePyObject ((Scene *)G.scene);
} }
@@ -288,12 +345,12 @@ PyObject *M_Scene_getCurrent (PyObject *self)
* \param pyobj BPy_Scene*: A Scene PyObject wrapper. * \param pyobj BPy_Scene*: A Scene PyObject wrapper.
*/ */
PyObject *M_Scene_unlink (PyObject *self, PyObject *arg) static PyObject *M_Scene_unlink (PyObject *self, PyObject *args)
{ {
PyObject *pyobj; PyObject *pyobj;
Scene *scene; Scene *scene;
if (!PyArg_ParseTuple (arg, "O!", &Scene_Type, &pyobj)) if (!PyArg_ParseTuple (args, "O!", &Scene_Type, &pyobj))
return EXPP_ReturnPyObjError (PyExc_TypeError, return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected Scene PyType object"); "expected Scene PyType object");
@@ -430,6 +487,392 @@ static PyObject *Scene_setName(BPy_Scene *self, PyObject *args)
return Py_None; return Py_None;
} }
/**
* \brief Scene PyMethod copy
*
* This function makes a copy of the scene (self). The optional argument
* can be:\n 0: Link Objects \n1: Link Object Data (default)\n2: Full copy
* \param dup_objs - int: how the scene children are duplicated.
* \return PyObject*: A pointer to the created copy of the scene.
*/
static PyObject *Scene_copy (BPy_Scene *self, PyObject *args)
{
short dup_objs = 1;
Scene *scene = self->scene;
if (!scene)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender Scene was deleted!");
if (!PyArg_ParseTuple (args, "|h", &dup_objs))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected int in [0,2] or nothing as argument");
return Scene_CreatePyObject (copy_scene (scene, dup_objs));
}
/**
* \brief Scene PyMethod currentFrame
*
* If frame is given, the current frame is set and returned in any case.
* \param frame int: The value for the current frame.
* \return int: The current frame.
*/
/* Blender seems to accept any positive value up to 18000 for start, end and
* current frames, independently. */
static PyObject *Scene_currentFrame (BPy_Scene *self, PyObject *args)
{
short frame = -1;
RenderData *rd = &self->scene->r;
if (!PyArg_ParseTuple (args, "|h", &frame))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected int argument or nothing");
if (frame > 0) rd->cfra = EXPP_ClampInt(frame, 1, EXPP_SCENE_FRAME_MAX);
return PyInt_FromLong (rd->cfra);
}
/**
* \brief Scene PyMethod startFrame
*
* If frame is given, the start frame is set and returned in any case.
* \param frame int: The value for the start frame.
* \return int: The start frame.
*/
static PyObject *Scene_startFrame (BPy_Scene *self, PyObject *args)
{
short frame = -1;
RenderData *rd = &self->scene->r;
if (!PyArg_ParseTuple (args, "|h", &frame))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected int argument or nothing");
if (frame > 0) rd->sfra = EXPP_ClampInt (frame, 1, EXPP_SCENE_FRAME_MAX);
return PyInt_FromLong (rd->sfra);
}
/**
* \brief Scene PyMethod endFrame
*
* If frame is given, the end frame is set and returned in any case.
* \param frame int: The value for the end frame.
* \return int: The end frame.
*/
static PyObject *Scene_endFrame (BPy_Scene *self, PyObject *args)
{
short frame = -1;
RenderData *rd = &self->scene->r;
if (!PyArg_ParseTuple (args, "|h", &frame))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected int argument or nothing");
if (frame > 0) rd->efra = EXPP_ClampInt (frame, 1, EXPP_SCENE_FRAME_MAX);
return PyInt_FromLong (rd->efra);
}
/**
* \brief Scene PyMethod makeCurrent
*
* Make self the current scene.
*/
static PyObject *Scene_makeCurrent (BPy_Scene *self)
{
Scene *scene = self->scene;
if (scene) set_scene (scene);
Py_INCREF (Py_None);
return Py_None;
}
/**
* \brief Scene PyMethod update
*
* Updates scene self. This function explicitely resorts the base list of
* a newly created object hierarchy.
*/
static PyObject *Scene_update (BPy_Scene *self)
{
Scene *scene = self->scene;
if (scene) sort_baselist (scene);
Py_INCREF (Py_None);
return Py_None;
}
/**
* \brief Scene PyMethod link
*
* Link the given object to this scene.
* \param object PyObject*: A pointer to an Object Python wrapper.
*/
static PyObject *Scene_link (BPy_Scene *self, PyObject *args)
{
Scene *scene = self->scene;
C_Object *bpy_obj; /* XXX Change to BPy or whatever is chosen */
if (!scene)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender Scene was deleted!");
if (!PyArg_ParseTuple (args, "O!", &Object_Type, &bpy_obj))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected Object argument");
else { /* Ok, all is fine, let's try to link it */
Object *object = bpy_obj->object;
Base *base;
/* We need to link the object to a 'Base', then link this base
* to the scene. See DNA_scene_types.h ... */
/* First, check if the object isn't already in the scene */
base = EXPP_Scene_getObjectBase (scene, object);
/* if base is not NULL ... */
if (base) /* ... the object is already in one of the Scene Bases */
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"object already in scene!");
/* not linked, go get mem for a new base object */
base = MEM_callocN(sizeof(Base), "newbase");
if (!base)
return EXPP_ReturnPyObjError (PyExc_MemoryError,
"couldn't allocate new Base for object");
base->object = object; /* link object to the new base */
base->lay = object->lay;
base->flag = object->flag;
object->id.us += 1; /* incref the object user count in Blender */
BLI_addhead(&scene->base, base); /* finally, link new base to scene */
}
Py_INCREF (Py_None);
return Py_None;
}
/**
* \brief Scene PyMethod unlink
*
* Unlink (delete) the given object from this scene.
* \param object PyObject*: A pointer to a Blender Object Python wrapper.
* \return int: 1 for success, 0 for failure.
*/
static PyObject *Scene_unlink (BPy_Scene *self, PyObject *args)
{
C_Object *bpy_obj = NULL;
Object *object;
Scene *scene = self->scene;
Base *base;
short retval = 0;
if (!scene)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender scene was deleted!");
if (!PyArg_ParseTuple(args, "O!", &Object_Type, &bpy_obj))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected Object as argument");
object = bpy_obj->object;
/* is the object really in the scene? */
base = EXPP_Scene_getObjectBase(scene, object);
if (base) { /* if it is, remove it: */
BLI_remlink(&scene->base, base);
object->id.us -= 1;
MEM_freeN (base);
scene->basact = 0; /* in case the object was selected */
retval = 1;
}
return Py_BuildValue ("i", PyInt_FromLong (retval));
}
/**
* \brief Scene PyMethod getRenderdir
*
* \return string: The directory where rendered images are saved to.
*/
static PyObject *Scene_getRenderdir (BPy_Scene *self)
{
if (self->scene)
return PyString_FromString (self->scene->r.pic);
else
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender Scene was deleted!");
}
/**
* \brief Scene PyMethod getBackbufdir
*
* \return string: The backbuffer image location
*/
static PyObject *Scene_getBackbufdir (BPy_Scene *self)
{
if (self->scene)
return PyString_FromString (self->scene->r.backbuf);
else
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender Scene already deleted");
}
/**
* \brief Scene PyMethod frameSettings
*
* This method can be used to set (if the values are given) and in any case
* get a tuple representing the start, end and current frame values.
* \param start int: The optional start frame value;
* \param end int: The optional end frame value;
* \param current int: The optional current frame value.
* \return tuple: (start, end, current) frame values.
*/
static PyObject *Scene_frameSettings (BPy_Scene *self, PyObject *args)
{
int start = -1;
int end = -1;
int current = -1;
RenderData *rd = NULL;
Scene *scene = self->scene;
if (!scene)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender Scene was deleted!");
rd = &scene->r;
if (!PyArg_ParseTuple (args, "|iii", &start, &end, &current))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected three ints or nothing as arguments");
if (start > 0) rd->sfra = EXPP_ClampInt (start, 1, EXPP_SCENE_FRAME_MAX);
if (end > 0) rd->efra = EXPP_ClampInt (end, 1, EXPP_SCENE_FRAME_MAX);
if (current > 0) rd->cfra = EXPP_ClampInt (current, 1, EXPP_SCENE_FRAME_MAX);
return Py_BuildValue("(iii)", rd->sfra, rd->efra, rd->cfra);
}
/**
* \brief Scene PyMethod getChildren
*
* \return PyList: a list of all objects linked to Scene self.
*/
static PyObject *Scene_getChildren (BPy_Scene *self)
{
Scene *scene = self->scene;
PyObject *pylist= PyList_New(0);
PyObject *bpy_obj;
Object *object;
Base *base;
if (!scene)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender Scene was deleted!");
base = scene->base.first;
while (base) {
object = base->object;
bpy_obj = M_Object_Get(Py_None,
Py_BuildValue ("(s)", object->id.name+2));
if (!bpy_obj)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't create new object wrapper");
PyList_Append (pylist, bpy_obj);
Py_XDECREF (bpy_obj); /* PyList_Append incref'ed it */
base = base->next;
}
return pylist;
}
/**
* \brief Scene PyMethod getCurrentCamera
*
* \return PyObject*: A wrapper for the currently active camera
*/
static PyObject *Scene_getCurrentCamera (BPy_Scene *self)
{
Object *cam_obj;
Scene *scene = self->scene;
if (!scene)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender Scene was deleted!");
cam_obj = scene->camera;
if (cam_obj) /* if found, return a wrapper for it */
return M_Object_Get (Py_None, Py_BuildValue ("(s)", cam_obj->id.name+2));
Py_INCREF(Py_None); /* none found */
return Py_None;
}
/**
* \brief Scene PyMethod setCurrentCamera
*
* Set the currently active Camera Object in Blender.
* \param cam_obj PyObject*: A Camera PyObject.
*/
static PyObject *Scene_setCurrentCamera (BPy_Scene *self, PyObject *args)
{
Object *object;
C_Object *cam_obj;
Scene *scene = self->scene;
if (!scene)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Blender Scene was deleted!");
if (!PyArg_ParseTuple(args, "O!", &Object_Type, &cam_obj))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected Camera Object as argument");
object = cam_obj->object;
scene->camera = object; /* set the current Camera */
/* if this is the current scene, update its window now */
if (scene == G.scene) copy_view3d_lock(REDRAW);
/* XXX copy_view3d_lock(REDRAW) prints "bad call to addqueue: 0 (18, 1)".
* The same happens in bpython. */
Py_INCREF(Py_None);
return Py_None;
}
/*@}*/ /*@}*/
/** /**
@@ -499,7 +942,7 @@ static int Scene_SetAttr (BPy_Scene *self, char *name, PyObject *value)
/* First we put "value" in a tuple, because we want to pass it to functions /* First we put "value" in a tuple, because we want to pass it to functions
* that only accept PyTuples. Using "N" doesn't increment value's ref count */ * that only accept PyTuples. Using "N" doesn't increment value's ref count */
valtuple = Py_BuildValue("(N)", value); valtuple = Py_BuildValue("(O)", value);
if (!valtuple) /* everything OK with our PyObject? */ if (!valtuple) /* everything OK with our PyObject? */
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,
@@ -569,3 +1012,28 @@ static PyObject *Scene_Repr (BPy_Scene *self)
} }
/*@}*/ /*@}*/
/**
* \brief Internal helper function to search the Base of an Object
*
* This function looks up the linked list of Bases in a scene, searching
* for a given object.
* \param scene Scene*: A pointer to a Blender Scene;
* \param object Object*: A pointer to a Blender Object.
* \return The Base* to the Base where object was stored or NULL if the
* object isn't linked to this scene.
*/
Base *EXPP_Scene_getObjectBase(Scene *scene, Object *object)
{
Base *base = scene->base.first;
while (base) {
if (object == base->object) return base; /* found it? */
base = base->next;
}
return NULL; /* object isn't linked to this scene */
}

View File

@@ -421,7 +421,7 @@ static int TextSetAttr (C_Text *self, char *name, PyObject *value)
* function anyway, since it already has error checking, clamps to the right * function anyway, since it already has error checking, clamps to the right
* interval and updates the Blender Text structure when necessary. */ * interval and updates the Blender Text structure when necessary. */
valtuple = Py_BuildValue("(N)", value); /* the set* functions expect a tuple */ valtuple = Py_BuildValue("(O)", value); /* the set* functions expect a tuple */
if (!valtuple) if (!valtuple)
return EXPP_ReturnIntError(PyExc_MemoryError, return EXPP_ReturnIntError(PyExc_MemoryError,

View File

@@ -74,6 +74,9 @@ PyObject * M_Types_Init (void);
/* NMesh Data */ /* NMesh Data */
PyObject * M_NMesh_Init (void); PyObject * M_NMesh_Init (void);
PyObject * NMesh_CreatePyObject (struct Camera *cam);
Camera * NMesh_FromPyObject (PyObject *pyobj);
int NMesh_CheckPyObject (PyObject *pyobj);
/* Material */ /* Material */
PyObject * M_Material_Init (void); PyObject * M_Material_Init (void);