This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/python/api2_2x/Object.c
Willian Padovani Germano e7d3039d12 - Blender: added option 'scriptsdir' to Blender.Get();
- small updates to the docs;
- Object: small fix to getMatrix: check during_script() to avoid undesired loops; added old behavior (pre 2.34) as option: .getMatrix('oldlocal');
- tentative fix for bug #1275: scene REDRAW scriptlinks were not being executed (the call to do so was missing):
http://projects.blender.org/tracker/index.php?func=detail&aid=1275&group_id=9&atid=125
    added the call in drawview.c, in drawview3dspace().  This causes the scriptlink to be called for each visible view3d, but that's what happens with object redraw scriptlinks, too.  Anyway, this is still a test.  The place was chosen based on the idea that a scene redraw scriptlink is like an object redraw one, but for all objs in the scene at once.

- Window.Theme: new submodule, to get/set theme options in Blender;
- Added the script save_theme.py (Help menu for now), to save the current theme in Blender as an executable script (currently shown in the Scripts->Misc menu).

There's more work to do for themes, like defining a proper place for them in the interface, adding documentation (for now the added script and the ones it generates can give a pretty good idea of how to use the new module), probably extending themes to support SpaceScript and so on.
2004-09-21 05:28:17 +00:00

2449 lines
70 KiB
C

/*
* $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 Object module provides generic access to Objects of various types via
* the Python interface.
*
*
* Contributor(s): Michel Selten, Willian Germano, Jacques Guignot,
* Joseph Gilbert, Stephen Swaney, Bala Gi, Campbell Barton
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include "Object.h"
#include "NLA.h"
#include "logic.h"
#include <blendef.h>
#include <DNA_scene_types.h>
#include <DNA_property_types.h>
#include <BSE_edit.h>
#include <BKE_property.h>
#include <BKE_mball.h>
#include <BIF_editview.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);
PyObject *M_Object_get(PyObject *self, PyObject *args);
static PyObject *M_Object_GetSelected (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},
{"getSelected", (PyCFunction)M_Object_getSelected, METH_VARARGS,
M_Object_GetSelected_doc},
{NULL, NULL, 0, NULL}
};
/*****************************************************************************/
/* Python BPy_Object methods declarations: */
/*****************************************************************************/
static PyObject *Object_buildParts (BPy_Object *self);
static PyObject *Object_clearIpo (BPy_Object *self);
static PyObject *Object_clrParent (BPy_Object *self, PyObject *args);
static PyObject *Object_clearTrack (BPy_Object *self, PyObject *args);
static PyObject *Object_getData (BPy_Object *self);
static PyObject *Object_getDeltaLocation (BPy_Object *self);
static PyObject *Object_getDrawMode (BPy_Object *self);
static PyObject *Object_getDrawType (BPy_Object *self);
static PyObject *Object_getEuler (BPy_Object *self);
static PyObject *Object_getInverseMatrix (BPy_Object *self);
static PyObject *Object_getIpo (BPy_Object *self);
static PyObject *Object_getLocation (BPy_Object *self, PyObject *args);
static PyObject *Object_getMaterials (BPy_Object *self, PyObject *args);
static PyObject *Object_getMatrix (BPy_Object *self, PyObject *args);
static PyObject *Object_getName (BPy_Object *self);
static PyObject *Object_getParent (BPy_Object *self);
static PyObject *Object_getSize (BPy_Object *self, PyObject *args);
static PyObject *Object_getTimeOffset (BPy_Object *self);
static PyObject *Object_getTracked (BPy_Object *self);
static PyObject *Object_getType (BPy_Object *self);
static PyObject *Object_getBoundBox (BPy_Object *self);
static PyObject *Object_getAction (BPy_Object *self);
static PyObject *Object_isSelected (BPy_Object *self);
static PyObject *Object_makeDisplayList (BPy_Object *self);
static PyObject *Object_link (BPy_Object *self, PyObject *args);
static PyObject *Object_makeParent (BPy_Object *self, PyObject *args);
static PyObject *Object_materialUsage (BPy_Object *self, PyObject *args);
static PyObject *Object_setDeltaLocation (BPy_Object *self, PyObject *args);
static PyObject *Object_setDrawMode (BPy_Object *self, PyObject *args);
static PyObject *Object_setDrawType (BPy_Object *self, PyObject *args);
static PyObject *Object_setEuler (BPy_Object *self, PyObject *args);\
static PyObject *Object_setMatrix (BPy_Object *self, PyObject *args);
static PyObject *Object_setIpo (BPy_Object *self, PyObject *args);
static PyObject *Object_setLocation (BPy_Object *self, PyObject *args);
static PyObject *Object_setMaterials (BPy_Object *self, PyObject *args);
static PyObject *Object_setName (BPy_Object *self, PyObject *args);
static PyObject *Object_setSize (BPy_Object *self, PyObject *args);
static PyObject *Object_setTimeOffset (BPy_Object *self, PyObject *args);
static PyObject *Object_makeTrack (BPy_Object *self, PyObject *args);
static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args);
static PyObject *Object_Select (BPy_Object *self, PyObject *args);
static PyObject *Object_getAllProperties (BPy_Object *self);
static PyObject *Object_addProperty(BPy_Object *self, PyObject *args);
static PyObject *Object_removeProperty(BPy_Object *self, PyObject *args);
static PyObject *Object_getProperty(BPy_Object *self, PyObject *args);
static PyObject *Object_removeAllProperties(BPy_Object *self);
static PyObject *Object_copyAllPropertiesTo(BPy_Object *self, PyObject *args);
static PyObject *Object_getScriptLinks(BPy_Object *self, PyObject *args);
static PyObject *Object_addScriptLink(BPy_Object *self, PyObject *args);
static PyObject *Object_clearScriptLinks(BPy_Object *self);
/*****************************************************************************/
/* Python BPy_Object methods table: */
/*****************************************************************************/
static PyMethodDef BPy_Object_methods[] = {
/* name, method, flags, doc */
{"buildParts", (PyCFunction)Object_buildParts, METH_NOARGS,
"Recalcs particle system (if any) "},
{"getIpo", (PyCFunction)Object_getIpo, METH_NOARGS,
"Returns the ipo of this object (if any) "},
{"clrParent", (PyCFunction)Object_clrParent, METH_VARARGS,
"Clears parent object. Optionally specify:\n\
mode\n\tnonzero: Keep object transform\nfast\n\t>0: Don't update scene \
hierarchy (faster)"},
{"clearTrack", (PyCFunction)Object_clearTrack, METH_VARARGS,
"Make this object not track another anymore. 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"},
{"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"},
{"getAction", (PyCFunction)Object_getAction, METH_NOARGS,
"Returns the active action for this object"},
{"isSelected", (PyCFunction)Object_isSelected, METH_NOARGS,
"Return a 1 or 0 depending on whether the object is selected"},
{"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_VARARGS,
"(i = 0) - Returns list of materials assigned to the object.\n\
if i is nonzero, empty slots are not ignored: they are returned as None's."},
{"getMatrix", (PyCFunction)Object_getMatrix, METH_VARARGS,
"(str = 'localspace') - Returns the object matrix.\n\
(str = 'localspace') - the wanted matrix: worldspace, localspace (default)\n\
or oldlocal (not updated, it was the only choice before Blender 2.34)."},
{"getName", (PyCFunction)Object_getName, METH_NOARGS,
"Returns the name of the object"},
{"getParent", (PyCFunction)Object_getParent, METH_NOARGS,
"Returns the object's parent object"},
{"getSize", (PyCFunction)Object_getSize, METH_VARARGS,
"Returns the object's size (x, y, z)"},
{"getTimeOffset", (PyCFunction)Object_getTimeOffset, METH_NOARGS,
"Returns the object's time offset"},
{"getTracked", (PyCFunction)Object_getTracked, METH_NOARGS,
"Returns the object's tracked object"},
{"getType", (PyCFunction)Object_getType, METH_NOARGS,
"Returns type of string of Object"},
{"getBoundBox", (PyCFunction)Object_getBoundBox, METH_NOARGS,
"Returns the object's bounding box"},
{"makeDisplayList", (PyCFunction)Object_makeDisplayList, METH_NOARGS,
"Update this object's Display List. Some changes like turning \n\
'SubSurf' on for a mesh need this method (followed by a Redraw) to \n\
show the changes on the 3d window."},
{"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\
fast:\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 returns 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"},
{"setMatrix", (PyCFunction)Object_setMatrix, METH_VARARGS,
"Set and apply a new matrix for the object"},
{"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."},
{"setName", (PyCFunction)Object_setName, METH_VARARGS,
"Sets the name of the object"},
{"setSize", (PyCFunction)Object_setSize, METH_VARARGS,
"Set the object's size. The first argument must be a vector\n\
triple."},
{"setTimeOffset", (PyCFunction)Object_setTimeOffset, METH_VARARGS,
"Set the object's time offset."},
{"makeTrack", (PyCFunction)Object_makeTrack, METH_VARARGS,
"(trackedobj, fast = 0) - Make this object track another.\n\
(trackedobj) - the object that will be tracked.\n\
(fast = 0) - if 0: update the scene hierarchy automatically. If you\n\
set 'fast' to a nonzero value, don't forget to update the scene yourself\n\
(see scene.update())."},
{"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."},
{"select", (PyCFunction)Object_Select, METH_VARARGS,
"( 1 or 0 ) - Set the selected state of the object.\n\
1 is selected, 0 not selected "},
{"setIpo", (PyCFunction)Object_setIpo, METH_VARARGS,
"(Blender Ipo) - Sets the object's ipo"},
{"clearIpo", (PyCFunction)Object_clearIpo, METH_NOARGS,
"() - Unlink ipo from this object"},
{"getAllProperties", (PyCFunction)Object_getAllProperties, METH_NOARGS,
"() - Get all the properties from this object"},
{"addProperty", (PyCFunction)Object_addProperty, METH_VARARGS,
"() - Add a property to this object"},
{"removeProperty", (PyCFunction)Object_removeProperty, METH_VARARGS,
"() - Remove a property from this object"},
{"getProperty", (PyCFunction)Object_getProperty, METH_VARARGS,
"() - Get a property from this object by name"},
{"removeAllProperties", (PyCFunction)Object_removeAllProperties, METH_NOARGS,
"() - removeAll a properties from this object"},
{"copyAllPropertiesTo", (PyCFunction)Object_copyAllPropertiesTo, METH_VARARGS,
"() - copy all properties from this object to another object"},
{"getScriptLinks", (PyCFunction)Object_getScriptLinks, METH_VARARGS,
"(eventname) - Get a list of this object's scriptlinks (Text names) "
"of the given type\n"
"(eventname) - string: FrameChanged or Redraw."},
{"addScriptLink", (PyCFunction)Object_addScriptLink, METH_VARARGS,
"(text, evt) - Add a new object scriptlink.\n"
"(text) - string: an existing Blender Text name;\n"
"(evt) string: FrameChanged or Redraw."},
{"clearScriptLinks", (PyCFunction)Object_clearScriptLinks, METH_NOARGS,
"() - Delete all scriptlinks from this object."},
{NULL, NULL, 0, NULL}
};
/*****************************************************************************/
/* PythonTypeObject callback function prototypes */
/*****************************************************************************/
static void Object_dealloc (BPy_Object *obj);
static PyObject* Object_getAttr (BPy_Object *obj, char *name);
static int Object_setAttr (BPy_Object *obj, char *name, PyObject *v);
static PyObject* Object_repr (BPy_Object *obj);
static int Object_compare (BPy_Object *a, BPy_Object *b);
/*****************************************************************************/
/* Python TypeObject structure definition. */
/*****************************************************************************/
PyTypeObject Object_Type =
{
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"Blender Object", /* tp_name */
sizeof (BPy_Object), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)Object_dealloc, /* tp_dealloc */
0, /* tp_print */
(getattrfunc)Object_getAttr, /* tp_getattr */
(setattrfunc)Object_setAttr, /* tp_setattr */
(cmpfunc)Object_compare, /* tp_compare */
(reprfunc)Object_repr, /* 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,
BPy_Object_methods, /* tp_methods */
0, /* tp_members */
};
/*****************************************************************************/
/* Function: M_Object_New */
/* Python equivalent: Blender.Object.New */
/*****************************************************************************/
PyObject *M_Object_New(PyObject *self, PyObject *args)
{
struct Object * object;
BPy_Object * blen_object;
int type;
char * str_type;
char * name = NULL;
if (!PyArg_ParseTuple(args, "s|s", &str_type, &name))
{
EXPP_ReturnPyObjError (PyExc_TypeError, "string expected as argument");
return (NULL);
}
if (strcmp (str_type, "Armature") == 0) type = OB_ARMATURE;
else if (strcmp (str_type, "Camera") == 0) type = OB_CAMERA;
else if (strcmp (str_type, "Curve") == 0) type = OB_CURVE;
/* else if (strcmp (str_type, "Text") == 0) type = OB_FONT; */
/* else if (strcmp (str_type, "Ika") == 0) type = OB_IKA; */
else if (strcmp (str_type, "Lamp") == 0) type = OB_LAMP;
else if (strcmp (str_type, "Lattice") == 0) type = OB_LATTICE;
else if (strcmp (str_type, "Mball") == 0) type = OB_MBALL;
else if (strcmp (str_type, "Mesh") == 0) type = OB_MESH;
else if (strcmp (str_type, "Surf") == 0) type = OB_SURF;
/* else if (strcmp (str_type, "Wave") == 0) type = OB_WAVE; */
else if (strcmp (str_type, "Empty") == 0) type = OB_EMPTY;
else
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"Unknown type specified"));
}
/* Create a new object. */
if (name == NULL)
{
/* No name is specified, set the name to the type of the object. */
name = str_type;
}
object = alloc_libblock (&(G.main->object), ID_OB, name);
object->id.us = 0;
object->flag = 0;
object->type = type;
/* transforms */
QuatOne(object->quat);
QuatOne(object->dquat);
object->col[3]= 1.0; // alpha
object->size[0] = object->size[1] = object->size[2] = 1.0;
object->loc[0] = object->loc[1] = object->loc[2] = 0.0;
Mat4One(object->parentinv);
Mat4One(object->obmat);
object->dt = OB_SHADED; // drawtype
if (U.flag & USER_MAT_ON_OB)
{
object->colbits = -1;
}
switch (object->type)
{
case OB_CAMERA: /* fall through. */
case OB_LAMP:
object->trackflag = OB_NEGZ;
object->upflag = OB_POSY;
break;
default:
object->trackflag = OB_POSY;
object->upflag = OB_POSZ;
}
object->ipoflag = OB_OFFS_OB + OB_OFFS_PARENT;
/* duplivert settings */
object->dupon = 1;
object->dupoff = 0;
object->dupsta = 1;
object->dupend = 100;
/* Gameengine defaults*/
object->mass = 1.0;
object->inertia = 1.0;
object->formfactor = 0.4;
object->damping = 0.04;
object->rdamping = 0.1;
object->anisotropicFriction[0] = 1.0;
object->anisotropicFriction[1] = 1.0;
object->anisotropicFriction[2] = 1.0;
object->gameflag = OB_PROP;
object->lay = 1; // Layer, by default visible
G.totobj++;
object->data = NULL;
/* Create a Python object from it. */
blen_object = (BPy_Object*)PyObject_NEW (BPy_Object, &Object_Type);
blen_object->object = object;
return ((PyObject*)blen_object);
}
/*****************************************************************************/
/* Function: M_Object_Get */
/* Python equivalent: Blender.Object.Get */
/*****************************************************************************/
PyObject *M_Object_Get(PyObject *self, PyObject *args)
{
struct Object * object;
BPy_Object * blen_object;
char * name = NULL;
PyArg_ParseTuple(args, "|s", &name);
if (name != NULL)
{
object = GetObjectByName (name);
if (object == NULL)
{
/* No object exists with the name specified in the argument name. */
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"Unknown object specified."));
}
blen_object = (BPy_Object*)PyObject_NEW (BPy_Object, &Object_Type);
blen_object->object = object;
return ((PyObject*)blen_object);
}
else
{
/* No argument has been given. Return a list of all objects. */
PyObject * obj_list;
Link * link;
int index;
obj_list = PyList_New (BLI_countlist (&(G.main->object)));
if (obj_list == NULL)
{
return (EXPP_ReturnPyObjError (PyExc_SystemError,
"List creation failed."));
}
link = G.main->object.first;
index = 0;
while (link)
{
object = (Object*)link;
blen_object = (BPy_Object*)PyObject_NEW (BPy_Object, &Object_Type);
blen_object->object = object;
PyList_SetItem (obj_list, index, (PyObject*)blen_object);
index++;
link = link->next;
}
return (obj_list);
}
}
/*****************************************************************************/
/* Function: M_Object_get */
/* Python equivalent: Blender.Object.get */
/*****************************************************************************/
PyObject *M_Object_get(PyObject *self, PyObject *args)
{
PyErr_Warn (PyExc_DeprecationWarning,
"The Object.get() function will be removed in Blender 2.29\n" \
"Please update the script to use Object.Get");
return (M_Object_Get (self, args));
}
/*****************************************************************************/
/* Function: M_Object_GetSelected */
/* Python equivalent: Blender.Object.getSelected */
/*****************************************************************************/
static PyObject *M_Object_GetSelected (PyObject *self, PyObject *args)
{
BPy_Object * blen_object;
PyObject * list;
Base * base_iter;
if (G.vd == NULL)
{
// No 3d view has been initialized yet, simply return None
Py_INCREF (Py_None);
return Py_None;
}
list = PyList_New (0);
if ((G.scene->basact) &&
((G.scene->basact->flag & SELECT) &&
(G.scene->basact->lay & G.vd->lay)))
{
/* Active object is first in the list. */
blen_object = (BPy_Object*)PyObject_NEW (BPy_Object, &Object_Type);
if (blen_object == NULL)
{
Py_DECREF (list);
Py_INCREF (Py_None);
return (Py_None);
}
blen_object->object = G.scene->basact->object;
PyList_Append (list, (PyObject*)blen_object);
}
base_iter = G.scene->base.first;
while (base_iter)
{
if (((base_iter->flag & SELECT) &&
(base_iter->lay & G.vd->lay)) &&
(base_iter != G.scene->basact))
{
blen_object = (BPy_Object*)PyObject_NEW (BPy_Object, &Object_Type);
if (blen_object == NULL)
{
Py_DECREF (list);
Py_INCREF (Py_None);
return (Py_None);
}
blen_object->object = base_iter->object;
PyList_Append (list, (PyObject*)blen_object);
}
base_iter = base_iter->next;
}
return (list);
}
/*****************************************************************************/
/* Function: M_Object_getSelected */
/* Python equivalent: Blender.Object.getSelected */
/*****************************************************************************/
static PyObject *M_Object_getSelected (PyObject *self, PyObject *args)
{
PyErr_Warn (PyExc_DeprecationWarning,
"The Object.getSelected() function will be removed in "\
"Blender 2.29\n" \
"Please update the script to use Object.GetSelected");
return (M_Object_GetSelected (self, args));
}
/*****************************************************************************/
/* Function: initObject */
/*****************************************************************************/
PyObject *Object_Init (void)
{
PyObject * module;
Object_Type.ob_type = &PyType_Type;
module = Py_InitModule3("Blender.Object", M_Object_methods, M_Object_doc);
return (module);
}
/*****************************************************************************/
/* Python BPy_Object methods: */
/*****************************************************************************/
static PyObject *Object_buildParts (BPy_Object *self)
{
void build_particle_system(Object *ob);
struct Object *obj = self->object;
build_particle_system(obj);
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_clearIpo(BPy_Object *self)
{
Object *ob = self->object;
Ipo *ipo = (Ipo *)ob->ipo;
if (ipo) {
ID *id = &ipo->id;
if (id->us > 0) id->us--;
ob->ipo = NULL;
Py_INCREF (Py_True);
return Py_True;
}
Py_INCREF (Py_False); /* no ipo found */
return Py_False;
}
static PyObject *Object_clrParent (BPy_Object *self, PyObject *args)
{
int mode=0;
int fast=0;
if (!PyArg_ParseTuple (args, "|ii", &mode, &fast))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected one or two integers as arguments"));
}
/* Remove the link only, the object is still in the scene. */
self->object->parent = NULL;
if (mode == 2)
{
/* Keep transform */
apply_obmat (self->object);
}
if (!fast)
{
sort_baselist (G.scene);
}
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_clearTrack (BPy_Object *self, PyObject *args)
{
int mode=0;
int fast=0;
if (!PyArg_ParseTuple (args, "|ii", &mode, &fast))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected one or two integers as arguments"));
}
/* Remove the link only, the object is still in the scene. */
self->object->track = NULL;
if (mode)
{
/* Keep transform */
apply_obmat (self->object);
}
if (!fast)
{
sort_baselist (G.scene);
}
Py_INCREF (Py_None);
return (Py_None);
}
/* adds object data to a Blender object, if object->data = NULL */
int EXPP_add_obdata(struct Object *object)
{
if (object->data != NULL) return -1;
switch(object->type)
{
case OB_ARMATURE:
/* TODO: Do we need to add something to G? (see the OB_LAMP case) */
object->data = add_armature();
break;
case OB_CAMERA:
/* TODO: Do we need to add something to G? (see the OB_LAMP case) */
object->data = add_camera();
break;
case OB_CURVE:
object->data = add_curve(OB_CURVE);
G.totcurve++;
break;
case OB_LAMP:
object->data = add_lamp();
G.totlamp++;
break;
case OB_MESH:
object->data = add_mesh();
G.totmesh++;
break;
case OB_LATTICE:
object->data = (void *)add_lattice();
object->dt = OB_WIRE;
break;
case OB_MBALL:
object->data = add_mball();
break;
/* TODO the following types will be supported later
case OB_SURF:
object->data = add_curve(OB_SURF);
G.totcurve++;
break;
case OB_FONT:
object->data = add_curve(OB_FONT);
break;
case OB_IKA:
object->data = add_ika();
object->dt = OB_WIRE;
break;
case OB_WAVE:
object->data = add_wave();
break;
*/
default:
break;
}
if (!object->data) return -1;
return 0;
}
static PyObject *Object_getData (BPy_Object *self)
{
PyObject * data_object;
Object * object = self->object;
/* if there's no obdata, try to create it */
if (object->data == NULL)
{
if (EXPP_add_obdata(object) != 0)
{ /* couldn't create obdata */
Py_INCREF (Py_None);
return (Py_None);
}
}
data_object = NULL;
switch (object->type)
{
case OB_ARMATURE:
data_object = Armature_CreatePyObject (object->data);
break;
case OB_CAMERA:
data_object = Camera_CreatePyObject (object->data);
break;
case OB_CURVE:
data_object = Curve_CreatePyObject (object->data);
break;
case ID_IM:
data_object = Image_CreatePyObject (object->data);
break;
case ID_IP:
data_object = Ipo_CreatePyObject (object->data);
break;
case OB_LAMP:
data_object = Lamp_CreatePyObject (object->data);
break;
case OB_LATTICE:
data_object = Lattice_CreatePyObject (object->data);
break;
case ID_MA:
break;
case OB_MESH:
data_object = NMesh_CreatePyObject (object->data, object);
break;
case ID_OB:
data_object = Object_CreatePyObject (object->data);
break;
case ID_SCE:
break;
case ID_TXT:
data_object = Text_CreatePyObject (object->data);
break;
case ID_WO:
break;
default:
break;
}
if (data_object == NULL)
{
Py_INCREF (Py_None);
return (Py_None);
}
else
{
return (data_object);
}
}
static PyObject *Object_getDeltaLocation (BPy_Object *self)
{
PyObject *attr = Py_BuildValue ("fff",
self->object->dloc[0],
self->object->dloc[1],
self->object->dloc[2]);
if (attr) return (attr);
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get Object.dloc attributes"));
}
static PyObject *Object_getDrawMode (BPy_Object *self)
{
PyObject *attr = Py_BuildValue ("b", self->object->dtx);
if (attr) return (attr);
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get Object.drawMode attribute"));
}
static PyObject *Object_getAction (BPy_Object *self)
{
/*BPy_Action *py_action = NULL;*/
if(!self->object->action){
Py_INCREF (Py_None);
return (Py_None);
}else{
return Action_CreatePyObject (self->object->action);
}
}
static PyObject *Object_isSelected (BPy_Object *self)
{
Base *base;
base= FIRSTBASE;
while (base) {
if (base->object == self->object) {
if (base->flag & SELECT) {
Py_INCREF (Py_True);
return Py_True;
} else {
Py_INCREF (Py_False);
return Py_False;
}
}
base= base->next;
}
return ( EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Internal error: could not find objects selection state"));
}
static PyObject *Object_getDrawType (BPy_Object *self)
{
PyObject *attr = Py_BuildValue ("b", self->object->dt);
if (attr) return (attr);
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get Object.drawType attribute"));
}
static PyObject *Object_getEuler (BPy_Object *self)
{
EulerObject *eul;
eul = (EulerObject*)newEulerObject(NULL);
eul->eul[0] = self->object->rot[0];
eul->eul[1] = self->object->rot[1];
eul->eul[2] = self->object->rot[2];
return (PyObject*)eul;
}
static PyObject *Object_getInverseMatrix (BPy_Object *self)
{
MatrixObject *inverse = (MatrixObject *)newMatrixObject(NULL, 4, 4);
Mat4Invert (*inverse->matrix, self->object->obmat);
return ((PyObject *)inverse);
}
static PyObject *Object_getIpo(BPy_Object *self)
{
struct Ipo *ipo = self->object->ipo;
if (!ipo)
{
Py_INCREF (Py_None);
return Py_None;
}
return Ipo_CreatePyObject (ipo);
}
static PyObject *Object_getLocation (BPy_Object *self, PyObject *args)
{
PyObject *attr = Py_BuildValue ("fff",
self->object->loc[0],
self->object->loc[1],
self->object->loc[2]);
if (attr) return (attr);
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get Object.loc attributes"));
}
static PyObject *Object_getMaterials (BPy_Object *self, PyObject *args)
{
int all = 0;
if (!PyArg_ParseTuple(args, "|i", &all)){
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected an int or nothing"));
}
return (EXPP_PyList_fromMaterialList (self->object->mat,
self->object->totcol, all));
}
static PyObject *Object_getMatrix (BPy_Object *self, PyObject *args)
{
PyObject *matrix;
char *space = "localspace"; /* default to local */
if (!PyArg_ParseTuple(args, "|s", &space)){
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a string or nothing"));
}
//new matrix
matrix = newMatrixObject(NULL, 4, 4);
if (BLI_streq(space, "worldspace")){ /* Worldspace matrix */
disable_where_script(1);
where_is_object(self->object);
disable_where_script(0);
Mat4CpyMat4(*((MatrixObject*)matrix)->matrix, self->object->obmat);
} else if (BLI_streq(space, "localspace")) { /* Localspace matrix*/
object_to_mat4(self->object, *((MatrixObject*)matrix)->matrix);
} else if (BLI_streq(space, "oldlocal")) { /* old behavior, prior to 2.34 */
Mat4CpyMat4(*((MatrixObject *)matrix)->matrix, self->object->obmat);
} else {
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"wrong parameter, expected nothing or either 'localspace' (default),\n\
'worldspace' or 'oldlocal'"));
}
return matrix;
}
static PyObject *Object_getName (BPy_Object *self)
{
PyObject *attr = Py_BuildValue ("s", self->object->id.name+2);
if (attr) return (attr);
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get the name of the Object"));
}
static PyObject *Object_getParent (BPy_Object *self)
{
PyObject *attr;
if (self->object->parent == NULL)
return EXPP_incr_ret (Py_None);
attr = Object_CreatePyObject (self->object->parent);
if (attr)
{
return (attr);
}
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get Object.parent attribute"));
}
static PyObject *Object_getSize (BPy_Object *self, PyObject *args)
{
PyObject *attr = Py_BuildValue ("fff",
self->object->size[0],
self->object->size[1],
self->object->size[2]);
if (attr) return (attr);
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get Object.size attributes"));
}
static PyObject *Object_getTimeOffset (BPy_Object *self)
{
PyObject *attr = Py_BuildValue ("f", self->object->sf);
if (attr) return (attr);
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get Object.sf attributes"));
}
static PyObject *Object_getTracked (BPy_Object *self)
{
PyObject *attr;
if (self->object->track == NULL)
return EXPP_incr_ret (Py_None);
attr = Object_CreatePyObject (self->object->track);
if (attr)
{
return (attr);
}
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't get Object.track attribute"));
}
static PyObject *Object_getType (BPy_Object *self)
{
switch (self->object->type)
{
case OB_ARMATURE: return (Py_BuildValue ("s", "Armature"));
case OB_CAMERA: return (Py_BuildValue ("s", "Camera"));
case OB_CURVE: return (Py_BuildValue ("s", "Curve"));
case OB_EMPTY: return (Py_BuildValue ("s", "Empty"));
case OB_FONT: return (Py_BuildValue ("s", "Text"));
case OB_IKA: return (Py_BuildValue ("s", "Ika"));
case OB_LAMP: return (Py_BuildValue ("s", "Lamp"));
case OB_LATTICE: return (Py_BuildValue ("s", "Lattice"));
case OB_MBALL: return (Py_BuildValue ("s", "MBall"));
case OB_MESH: return (Py_BuildValue ("s", "Mesh"));
case OB_SURF: return (Py_BuildValue ("s", "Surf"));
case OB_WAVE: return (Py_BuildValue ("s", "Wave"));
default: return (Py_BuildValue ("s", "unknown"));
}
}
static PyObject *Object_getBoundBox (BPy_Object *self)
{
int i;
float *vec = NULL;
PyObject *vector, *bbox;
if (!self->object->data)
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"This object isn't linked to any object data (mesh, curve, etc) yet");
if (!self->object->bb) { /* if no ob bbox, we look in obdata */
Mesh *me;
Curve *curve;
switch (self->object->type) {
case OB_MESH:
me = self->object->data;
if (!me->bb) tex_space_mesh(me);
vec = (float *)me->bb->vec;
break;
case OB_CURVE:
case OB_FONT:
case OB_SURF:
curve = self->object->data;
if (!curve->bb) tex_space_curve(curve);
vec = (float *)curve->bb->vec;
break;
default:
Py_INCREF (Py_None);
return Py_None;
}
{ /* transform our obdata bbox by the obmat.
the obmat is 4x4 homogeneous coords matrix.
each bbox coord is xyz, so we make it homogenous
by padding it with w=1.0 and doing the matrix mult.
afterwards we divide by w to get back to xyz.
*/
/* printmatrix4( "obmat", self->object->obmat); */
float tmpvec[4]; /* tmp vector for homogenous coords math */
int i;
float *from;
bbox = PyList_New(8);
if (!bbox)
return EXPP_ReturnPyObjError (PyExc_MemoryError,
"couldn't create pylist");
for( i = 0, from = vec;
i < 8;
i++, from += 3 ) {
memcpy( tmpvec, from, 3*sizeof(float));
tmpvec[3]=1.0f; /* set w coord */
Mat4MulVec4fl( self->object->obmat, tmpvec );
/* divide x,y,z by w */
tmpvec[0] /= tmpvec[3];
tmpvec[1] /= tmpvec[3];
tmpvec[2] /= tmpvec[3];
#if 0
{ /* debug print stuff */
int i;
printf("\nobj bbox transformed\n");
for( i=0; i<4; ++i)
printf( "%f ", tmpvec[i]);
printf("\n");
}
#endif
/* because our bounding box is calculated and
does not have its own memory,
we must create vectors that allocate space */
vector = newVectorObject( NULL, 3);
memcpy( ((VectorObject*)vector)->vec,
tmpvec,
3*sizeof(float));
PyList_SET_ITEM(bbox, i, vector);
}
}
}
else{ /* the ob bbox exists */
vec = (float *)self->object->bb->vec;
if (!vec)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"couldn't retrieve bounding box data");
bbox = PyList_New(8);
if (!bbox)
return EXPP_ReturnPyObjError (PyExc_MemoryError,
"couldn't create pylist");
/* create vectors referencing object bounding box coords */
for (i = 0; i < 8; i++) {
vector = newVectorObject(vec, 3);
PyList_SET_ITEM(bbox, i, vector);
vec += 3;
}
}
return bbox;
}
static PyObject *Object_makeDisplayList (BPy_Object *self)
{
Object *ob = self->object;
if (ob->type == OB_FONT) text_to_curve(ob, 0);
makeDispList(ob);
Py_INCREF (Py_None);
return Py_None;
}
static PyObject *Object_link (BPy_Object *self, PyObject *args)
{
PyObject * py_data;
ID * id;
ID * oldid;
int obj_id;
void * data = NULL;
if (!PyArg_ParseTuple (args, "O", &py_data))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected an object as argument"));
}
if (Armature_CheckPyObject (py_data))
data = (void *)Armature_FromPyObject (py_data);
if (Camera_CheckPyObject (py_data))
data = (void *)Camera_FromPyObject (py_data);
if (Lamp_CheckPyObject (py_data))
data = (void *)Lamp_FromPyObject (py_data);
if (Curve_CheckPyObject (py_data))
data = (void *)Curve_FromPyObject (py_data);
if (NMesh_CheckPyObject (py_data))
data = (void *)Mesh_FromPyObject (py_data, self->object);
if (Lattice_CheckPyObject (py_data))
data = (void *)Lattice_FromPyObject (py_data);
if (Metaball_CheckPyObject (py_data))
data = (void *)Metaball_FromPyObject (py_data);
/* have we set data to something good? */
if( !data )
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"link argument type is not supported "));
}
oldid = (ID*) self->object->data;
id = (ID*) data;
obj_id = MAKE_ID2 (id->name[0], id->name[1]);
switch (obj_id)
{
case ID_AR:
if (self->object->type != OB_ARMATURE)
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"The 'link' object is incompatible with the base object"));
}
break;
case ID_CA:
if (self->object->type != OB_CAMERA)
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"The 'link' object is incompatible with the base object"));
}
break;
case ID_LA:
if (self->object->type != OB_LAMP)
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"The 'link' object is incompatible with the base object"));
}
break;
case ID_ME:
if (self->object->type != OB_MESH)
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"The 'link' object is incompatible with the base object"));
}
break;
case ID_CU:
if (self->object->type != OB_CURVE)
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"The 'link' object is incompatible with the base object"));
}
break;
case ID_LT:
if (self->object->type != OB_LATTICE)
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"The 'link' object is incompatible with the base object"));
}
break;
case ID_MB:
if (self->object->type != OB_MBALL)
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"The 'link' object is incompatible with the base object"));
}
break;
default:
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"Linking this object type is not supported"));
}
self->object->data = data;
if ( self->object->type == OB_MESH)
{
self->object->totcol = 0;
EXPP_synchronizeMaterialLists(self->object);
}
id_us_plus (id);
if (oldid)
{
if (oldid->us > 0)
{
oldid->us--;
}
else
{
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"old object reference count below 0"));
}
}
return EXPP_incr_ret (Py_None);
}
static PyObject *Object_makeParent (BPy_Object *self, PyObject *args)
{
PyObject * list;
PyObject * py_child;
//BPy_Object * py_obj_child; unused
Object * child;
Object * parent;
int noninverse = 0;
int fast = 0;
int i;
/* Check if the arguments passed to makeParent are valid. */
if (!PyArg_ParseTuple (args, "O|ii", &list, &noninverse, &fast))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a list of objects and one or two integers as arguments"));
}
if (!PySequence_Check (list))
{
return (EXPP_ReturnPyObjError (PyExc_TypeError,
"expected a list of objects"));
}
/* Check if the PyObject passed in list is a Blender object. */
for (i=0 ; i<PySequence_Length (list) ; i++)
{
child = NULL;
py_child = PySequence_GetItem (list, i);
if (Object_CheckPyObject (py_child))
child = (Object*) Object_FromPyObject (py_child);
if (child == NULL)
{
return (EXPP_ReturnPyObjError (PyExc_TypeError,
"Object Type expected"));
}
parent = (Object*)self->object;
if (test_parent_loop (parent, child))
{
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"parenting loop detected - parenting failed"));
}
child->partype = PAROBJECT;
child->parent = parent;
//py_obj_child = (BPy_Object *) py_child;
if (noninverse == 1)
{
/* Parent inverse = unity */
child->loc[0] = 0.0;
child->loc[1] = 0.0;
child->loc[2] = 0.0;
}
else
{
what_does_parent (child);
Mat4Invert (child->parentinv, parent->obmat);
}
if (!fast)
{
sort_baselist (G.scene);
}
// We don't need the child object anymore.
//Py_DECREF ((PyObject *) child);
}
return EXPP_incr_ret (Py_None);
}
static PyObject *Object_materialUsage (BPy_Object *self, PyObject *args)
{
return (EXPP_ReturnPyObjError (PyExc_NotImplementedError,
"materialUsage: not yet implemented"));
}
static PyObject *Object_setDeltaLocation (BPy_Object *self, PyObject *args)
{
float dloc1;
float dloc2;
float dloc3;
int status;
if (PyObject_Length (args) == 3)
status = PyArg_ParseTuple (args, "fff", &dloc1, &dloc2, &dloc3);
else
status = PyArg_ParseTuple (args, "(fff)", &dloc1, &dloc2, &dloc3);
if (!status)
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected list argument of 3 floats");
self->object->dloc[0] = dloc1;
self->object->dloc[1] = dloc2;
self->object->dloc[2] = dloc3;
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_setDrawMode (BPy_Object *self, PyObject *args)
{
char dtx;
if (!PyArg_ParseTuple (args, "b", &dtx))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected an integer as argument"));
}
self->object->dtx = dtx;
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_setDrawType (BPy_Object *self, PyObject *args)
{
char dt;
if (!PyArg_ParseTuple (args, "b", &dt))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected an integer as argument"));
}
self->object->dt = dt;
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_setEuler (BPy_Object *self, PyObject *args)
{
float rot1;
float rot2;
float rot3;
int status = 0; /* failure */
PyObject* ob;
/*
args is either a tuple/list of floats or an euler.
for backward compatibility, we also accept 3 floats.
*/
/* do we have 3 floats? */
if (PyObject_Length (args) == 3) {
status = PyArg_ParseTuple (args, "fff", &rot1, &rot2, &rot3);
}
else{ //test to see if it's a list or a euler
if ( PyArg_ParseTuple (args, "O", &ob)){
if(EulerObject_Check(ob)){
rot1 = ((EulerObject*)ob)->eul[0];
rot2 = ((EulerObject*)ob)->eul[1];
rot3 = ((EulerObject*)ob)->eul[2];
status = 1; /* success! */
}
else if(PySequence_Check(ob ))
status = PyArg_ParseTuple (args, "(fff)",
&rot1, &rot2, &rot3);
else{ /* not an euler or tuple */
/* python C api doc says don't decref this */
/*Py_DECREF (ob); */
status = 0; /* false */
}
}
else{ /* arg parsing failed */
status = 0;
}
}
if( !status) /* parsing args failed */
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected euler or list/tuple of 3 floats "));
self->object->rot[0] = rot1;
self->object->rot[1] = rot2;
self->object->rot[2] = rot3;
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_setMatrix (BPy_Object *self, PyObject *args)
{
MatrixObject* mat;
int x,y;
if (!PyArg_ParseTuple(args, "O!", &matrix_Type, &mat))
return EXPP_ReturnPyObjError
(PyExc_TypeError, "expected matrix object as argument");
for(x = 0; x < 4; x++){
for(y = 0; y < 4; y++){
self->object->obmat[x][y] = mat->matrix[x][y];
}
}
apply_obmat(self->object);
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_setIpo(BPy_Object *self, PyObject *args)
{
PyObject *pyipo = 0;
Ipo *ipo = NULL;
Ipo *oldipo;
if (!PyArg_ParseTuple(args, "O!", &Ipo_Type, &pyipo))
return EXPP_ReturnPyObjError (PyExc_TypeError, "expected Ipo as argument");
ipo = Ipo_FromPyObject(pyipo);
if (!ipo) return EXPP_ReturnPyObjError (PyExc_RuntimeError, "null ipo!");
if (ipo->blocktype != ID_OB)
return EXPP_ReturnPyObjError (PyExc_TypeError,
"this ipo is not an object ipo");
oldipo = self->object->ipo;
if (oldipo) {
ID *id = &oldipo->id;
if (id->us > 0) id->us--;
}
((ID *)&ipo->id)->us++;
self->object->ipo = ipo;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *Object_setLocation (BPy_Object *self, PyObject *args)
{
float loc1;
float loc2;
float loc3;
int status;
if (PyObject_Length (args) == 3)
status = PyArg_ParseTuple (args, "fff", &loc1, &loc2, &loc3);
else
status = PyArg_ParseTuple (args, "(fff)", &loc1, &loc2, &loc3);
if (!status)
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected list argument of 3 floats");
self->object->loc[0] = loc1;
self->object->loc[1] = loc2;
self->object->loc[2] = loc3;
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_setMaterials (BPy_Object *self, PyObject *args)
{
PyObject * list;
int len;
int i;
Material ** matlist;
if (!PyArg_ParseTuple (args, "O", &list))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a list of materials as argument"));
}
len = PySequence_Length (list);
if (len > 0)
{
matlist = EXPP_newMaterialList_fromPyList (list);
if (!matlist)
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"material list must be a list of valid materials!"));
}
if ((len < 0) || (len > MAXMAT))
{
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"material list should have at least 1, at most 16 entries"));
}
if (self->object->mat)
{
EXPP_releaseMaterialList (self->object->mat, self->object->totcol);
}
/* Increase the user count on all materials */
for (i=0 ; i<len ; i++)
{
if (matlist[i]) id_us_plus ((ID *) matlist[i]);
}
self->object->mat = matlist;
self->object->totcol = len;
self->object->actcol = len;
switch (self->object->type)
{
case OB_CURVE: /* fall through */
case OB_FONT: /* fall through */
case OB_MESH: /* fall through */
case OB_MBALL: /* fall through */
case OB_SURF:
EXPP_synchronizeMaterialLists (self->object);
break;
default:
break;
}
}
return EXPP_incr_ret (Py_None);
}
static PyObject *Object_setName (BPy_Object *self, PyObject *args)
{
char * name;
char buf[21];
if (!PyArg_ParseTuple (args, "s", &name))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a String as argument"));
}
PyOS_snprintf(buf, sizeof(buf), "%s", name);
rename_id(&self->object->id, buf);
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_setSize (BPy_Object *self, PyObject *args)
{
float sizex;
float sizey;
float sizez;
int status;
if (PyObject_Length (args) == 3)
status = PyArg_ParseTuple (args, "fff", &sizex, &sizey, &sizez);
else
status = PyArg_ParseTuple (args, "(fff)", &sizex, &sizey, &sizez);
if (!status)
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected list argument of 3 floats");
self->object->size[0] = sizex;
self->object->size[1] = sizey;
self->object->size[2] = sizez;
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_setTimeOffset (BPy_Object *self, PyObject *args)
{
float newTimeOffset;
if (!PyArg_ParseTuple (args, "f", &newTimeOffset))
{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a float as argument"));
}
self->object->sf=newTimeOffset;
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_makeTrack (BPy_Object *self, PyObject *args)
{
BPy_Object *tracked = NULL;
Object *ob = self->object;
int fast = 0;
if (!PyArg_ParseTuple (args, "O!|i", &Object_Type, &tracked, &fast))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected an object and optionally also an int as arguments.");
ob->track = tracked->object;
if (!fast) sort_baselist(G.scene);
return EXPP_incr_ret(Py_None);
}
static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args)
{
BPy_Object * object;
ID * id;
ID * oldid;
if (!PyArg_ParseTuple (args, "O", &object))
{
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected an object argument");
}
if (!Object_CheckPyObject ((PyObject*)object))
{
return EXPP_ReturnPyObjError (PyExc_TypeError,
"first argument is not of type 'Object'");
}
if (self->object->type != object->object->type)
{
return EXPP_ReturnPyObjError (PyExc_TypeError,
"objects are not of same data type");
}
switch (self->object->type)
{
case OB_MESH:
case OB_LAMP:
case OB_CAMERA: /* we can probably add the other types, too */
case OB_ARMATURE:
case OB_CURVE:
case OB_SURF:
case OB_LATTICE:
oldid = (ID*) self->object->data;
id = (ID*) object->object->data;
self->object->data = object->object->data;
if ( self->object->type == OB_MESH && id ){
self->object->totcol = 0;
EXPP_synchronizeMaterialLists(self->object);
}
id_us_plus (id);
if (oldid)
{
if (oldid->us > 0)
{
oldid->us--;
}
else
{
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"old object reference count below 0"));
}
}
Py_INCREF (Py_None);
return (Py_None);
default:
return EXPP_ReturnPyObjError (PyExc_TypeError,
"type not supported");
}
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_Select (BPy_Object *self, PyObject *args)
{
Base *base;
int sel;
base= FIRSTBASE;
if (!PyArg_ParseTuple (args, "i", &sel))
return EXPP_ReturnPyObjError
(PyExc_TypeError, "expected an integer, 0 or 1");
while (base) {
if (base->object == self->object){
if (sel == 1){
base->flag |= SELECT;
self->object->flag= base->flag;
set_active_base( base );
} else {
base->flag &= ~SELECT;
self->object->flag= base->flag;
}
break;
}
base= base->next;
}
countall();
Py_INCREF (Py_None);
return (Py_None);
}
static PyObject *Object_getAllProperties(BPy_Object *self)
{
PyObject *prop_list;
bProperty *prop= NULL;
prop_list = PyList_New(0);
prop = self->object->prop.first;
while(prop){
PyList_Append(prop_list, Property_CreatePyObject(prop));
prop = prop->next;
}
return prop_list;
}
static PyObject *Object_getProperty(BPy_Object *self, PyObject *args)
{
char *prop_name = NULL;
bProperty *prop= NULL;
PyObject *py_prop = Py_None;
if(!PyArg_ParseTuple (args, "s", &prop_name)){
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a string"));
}
prop = get_property(self->object, prop_name);
if(prop){
py_prop = Property_CreatePyObject(prop);
}else{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"couldn't find the property...."));
}
return py_prop;
}
static PyObject *Object_addProperty(BPy_Object *self, PyObject *args)
{
bProperty *prop = NULL;
char *prop_name = NULL;
PyObject *prop_data = Py_None;
char *prop_type = NULL;
short type = -1;
BPy_Property *py_prop = NULL;
if (PyObject_Length (args) == 3 || PyObject_Length (args) == 2){
if (!PyArg_ParseTuple (args, "sO|s", &prop_name, &prop_data, &prop_type)){
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"unable to get string, data, and optional string"));
}
}else if (PyObject_Length (args) == 1){
if (!PyArg_ParseTuple (args, "O!", &property_Type, &py_prop)){
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"unable to get Property"));
}
if(py_prop->property != NULL){
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"Property is already added to an object"));
}
}else{
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected 1,2 or 3 arguments"));
}
//parse property type
if(!py_prop){
if(prop_type){
if(BLI_streq(prop_type, "BOOL")) type = PROP_BOOL;
else if (BLI_streq(prop_type, "INT")) type = PROP_INT;
else if (BLI_streq(prop_type, "FLOAT")) type = PROP_FLOAT;
else if (BLI_streq(prop_type, "TIME")) type = PROP_TIME;
else if (BLI_streq(prop_type, "STRING")) type = PROP_STRING;
else return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"BOOL, INT, FLOAT, TIME or STRING expected"));
}else{
//use the default
if(PyInt_Check(prop_data)) type = PROP_INT;
else if (PyFloat_Check(prop_data)) type = PROP_FLOAT;
else if (PyString_Check(prop_data)) type = PROP_STRING;
}
}else{
type = py_prop->type;
}
//initialize a new bProperty of the specified type
prop = new_property(type);
//parse data
if(!py_prop){
BLI_strncpy(prop->name, prop_name, 32);
if(PyInt_Check(prop_data)){
*((int*)&prop->data) = (int)PyInt_AsLong(prop_data);
}else if (PyFloat_Check(prop_data)){
*((float *)&prop->data) = (float)PyFloat_AsDouble(prop_data);
}else if (PyString_Check(prop_data)){
BLI_strncpy(prop->poin, PyString_AsString(prop_data), MAX_PROPSTRING);
}
}else{
py_prop->property = prop;
if(!updateProperyData(py_prop)){
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Could not update property data - error"));
}
}
//add to property listbase for the object
BLI_addtail(&self->object->prop, prop);
return EXPP_incr_ret (Py_None);
}
static PyObject *Object_removeProperty(BPy_Object *self, PyObject *args)
{
char *prop_name = NULL;
BPy_Property *py_prop = NULL;
bProperty *prop = NULL;
// we have property and no optional arg
if (!PyArg_ParseTuple (args, "O!", &property_Type, &py_prop)){
if(!PyArg_ParseTuple (args, "s", &prop_name)){
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a Property or a string"));
}
}
//remove the link, free the data, and update the py struct
if(py_prop){
BLI_remlink(&self->object->prop, py_prop->property);
if(updatePyProperty(py_prop)){
free_property(py_prop->property);
py_prop->property = NULL;
}
}else{
prop = get_property(self->object, prop_name);
if(prop){
BLI_remlink(&self->object->prop, prop);
free_property(prop);
}
}
return EXPP_incr_ret (Py_None);
}
static PyObject *Object_removeAllProperties(BPy_Object *self)
{
free_properties(&self->object->prop);
return EXPP_incr_ret (Py_None);
}
static PyObject *Object_copyAllPropertiesTo(BPy_Object *self, PyObject *args)
{
PyObject *dest = Py_None;
bProperty *prop = NULL;
bProperty *propn = NULL;
if (!PyArg_ParseTuple (args, "O!", &Object_Type, &dest)){
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected an Object"));
}
//make a copy of all it's properties
prop = self->object->prop.first;
while(prop) {
propn= copy_property(prop);
BLI_addtail(&((BPy_Object*)dest)->object->prop, propn);
prop= prop->next;
}
return EXPP_incr_ret (Py_None);
}
/* obj.addScriptLink */
static PyObject *Object_addScriptLink (BPy_Object *self, PyObject *args)
{
Object *obj = self->object;
ScriptLink *slink = NULL;
slink = &(obj)->scriptlink;
if (!EXPP_addScriptLink(slink, args, 0))
return EXPP_incr_ret (Py_None);
else return NULL;
}
/* obj.clearScriptLinks */
static PyObject *Object_clearScriptLinks (BPy_Object *self)
{
Object *obj = self->object;
ScriptLink *slink = NULL;
slink = &(obj)->scriptlink;
return EXPP_incr_ret(Py_BuildValue("i", EXPP_clearScriptLinks (slink)));
}
/* obj.getScriptLinks */
static PyObject *Object_getScriptLinks (BPy_Object *self, PyObject *args)
{
Object *obj = self->object;
ScriptLink *slink = NULL;
PyObject *ret = NULL;
slink = &(obj)->scriptlink;
ret = EXPP_getScriptLinks(slink, args, 0);
if (ret) return ret;
else return NULL;
}
/*****************************************************************************/
/* Function: Object_CreatePyObject */
/* Description: This function will create a new BlenObject from an existing */
/* Object structure. */
/*****************************************************************************/
PyObject* Object_CreatePyObject (struct Object *obj)
{
BPy_Object * blen_object;
if (!obj) return EXPP_incr_ret (Py_None);
blen_object = (BPy_Object*)PyObject_NEW (BPy_Object, &Object_Type);
if (blen_object == NULL)
{
return (NULL);
}
blen_object->object = obj;
return ((PyObject*)blen_object);
}
/*****************************************************************************/
/* Function: Object_CheckPyObject */
/* Description: This function returns true when the given PyObject is of the */
/* type Object. Otherwise it will return false. */
/*****************************************************************************/
int Object_CheckPyObject (PyObject *py_obj)
{
return (py_obj->ob_type == &Object_Type);
}
/*****************************************************************************/
/* Function: Object_FromPyObject */
/* Description: This function returns the Blender object from the given */
/* PyObject. */
/*****************************************************************************/
struct Object* Object_FromPyObject (PyObject *py_obj)
{
BPy_Object * blen_obj;
blen_obj = (BPy_Object*)py_obj;
return (blen_obj->object);
}
/*****************************************************************************/
/* Description: Returns the object with the name specified by the argument */
/* name. Note that the calling function has to remove the first */
/* two characters of the object name. These two characters */
/* specify the type of the object (OB, ME, WO, ...) */
/* The function will return NULL when no object with the given */
/* name is found. */
/*****************************************************************************/
Object * GetObjectByName (char * name)
{
Object * obj_iter;
obj_iter = G.main->object.first;
while (obj_iter)
{
if (StringEqual (name, GetIdName (&(obj_iter->id))))
{
return (obj_iter);
}
obj_iter = obj_iter->id.next;
}
/* There is no object with the given name */
return (NULL);
}
/*****************************************************************************/
/* Function: Object_dealloc */
/* Description: This is a callback function for the BlenObject type. It is */
/* the destructor function. */
/*****************************************************************************/
static void Object_dealloc (BPy_Object *obj)
{
PyObject_DEL (obj);
}
/*****************************************************************************/
/* Function: Object_getAttr */
/* Description: This is a callback function for the BlenObject type. It is */
/* the function that retrieves any value from Blender and */
/* passes it to Python. */
/*****************************************************************************/
static PyObject* Object_getAttr (BPy_Object *obj, char *name)
{
struct Object * object;
struct Ika * ika;
object = obj->object;
if (StringEqual (name, "LocX"))
return (PyFloat_FromDouble(object->loc[0]));
if (StringEqual (name, "LocY"))
return (PyFloat_FromDouble(object->loc[1]));
if (StringEqual (name, "LocZ"))
return (PyFloat_FromDouble(object->loc[2]));
if (StringEqual (name, "loc"))
return (Py_BuildValue ("fff", object->loc[0], object->loc[1],
object->loc[2]));
if (StringEqual (name, "dLocX"))
return (PyFloat_FromDouble(object->dloc[0]));
if (StringEqual (name, "dLocY"))
return (PyFloat_FromDouble(object->dloc[1]));
if (StringEqual (name, "dLocZ"))
return (PyFloat_FromDouble(object->dloc[2]));
if (StringEqual (name, "dloc"))
return (Py_BuildValue ("fff", object->dloc[0], object->dloc[1],
object->dloc[2]));
if (StringEqual (name, "RotX"))
return (PyFloat_FromDouble(object->rot[0]));
if (StringEqual (name, "RotY"))
return (PyFloat_FromDouble(object->rot[1]));
if (StringEqual (name, "RotZ"))
return (PyFloat_FromDouble(object->rot[2]));
if (StringEqual (name, "rot"))
return (Py_BuildValue ("fff", object->rot[0], object->rot[1],
object->rot[2]));
if (StringEqual (name, "dRotX"))
return (PyFloat_FromDouble(object->drot[0]));
if (StringEqual (name, "dRotY"))
return (PyFloat_FromDouble(object->drot[1]));
if (StringEqual (name, "dRotZ"))
return (PyFloat_FromDouble(object->drot[2]));
if (StringEqual (name, "drot"))
return (Py_BuildValue ("fff", object->drot[0], object->drot[1],
object->drot[2]));
if (StringEqual (name, "SizeX"))
return (PyFloat_FromDouble(object->size[0]));
if (StringEqual (name, "SizeY"))
return (PyFloat_FromDouble(object->size[1]));
if (StringEqual (name, "SizeZ"))
return (PyFloat_FromDouble(object->size[2]));
if (StringEqual (name, "size"))
return (Py_BuildValue ("fff", object->size[0], object->size[1],
object->size[2]));
if (StringEqual (name, "dSizeX"))
return (PyFloat_FromDouble(object->dsize[0]));
if (StringEqual (name, "dSizeY"))
return (PyFloat_FromDouble(object->dsize[1]));
if (StringEqual (name, "dSizeZ"))
return (PyFloat_FromDouble(object->dsize[2]));
if (StringEqual (name, "dsize"))
return (Py_BuildValue ("fff", object->dsize[0], object->dsize[1],
object->dsize[2]));
if (strncmp (name,"Eff", 3) == 0)
{
if ( (object->type == OB_IKA) && (object->data != NULL) )
{
ika = object->data;
switch (name[3])
{
case 'X':
return (PyFloat_FromDouble (ika->effg[0]));
case 'Y':
return (PyFloat_FromDouble (ika->effg[1]));
case 'Z':
return (PyFloat_FromDouble (ika->effg[2]));
default:
/* Do we need to display a sensible error message here? */
return (NULL);
}
}
return (NULL);
}
if (StringEqual (name, "Layer"))
return (PyInt_FromLong(object->lay));
if (StringEqual (name, "parent"))
{
if (object->parent)
return (Object_CreatePyObject (object->parent));
else
{
Py_INCREF (Py_None);
return (Py_None);
}
}
if (StringEqual (name, "track"))
return (Object_CreatePyObject (object->track));
if (StringEqual (name, "data"))
return (Object_getData (obj));
if (StringEqual (name, "ipo"))
{
if (object->ipo == NULL)
{
/* There's no ipo linked to the object, return Py_None. */
Py_INCREF (Py_None);
return (Py_None);
}
return (Ipo_CreatePyObject (object->ipo));
}
if (StringEqual (name, "mat") || StringEqual (name, "matrix"))
return (Object_getMatrix (obj, Py_BuildValue("(s)","localspace")));
if (StringEqual (name, "matrixWorld"))
return (Object_getMatrix (obj, Py_BuildValue("(s)","worldspace")));
if (StringEqual (name, "matrixLocal"))
return (Object_getMatrix (obj, Py_BuildValue("(s)","localspace")));
if (StringEqual (name, "colbits"))
return (Py_BuildValue ("h", object->colbits));
if (StringEqual (name, "drawType"))
return (Py_BuildValue ("b", object->dt));
if (StringEqual (name, "drawMode"))
return (Py_BuildValue ("b", object->dtx));
if (StringEqual (name, "name"))
return (Py_BuildValue ("s", object->id.name+2));
if (StringEqual (name, "sel"))
return (Object_isSelected (obj));
/* not an attribute, search the methods table */
return Py_FindMethod(BPy_Object_methods, (PyObject *)obj, name);
}
/*****************************************************************************/
/* Function: Object_setAttr */
/* Description: This is a callback function for the BlenObject type. It is */
/* the function that retrieves any value from Python and sets */
/* it accordingly in Blender. */
/*****************************************************************************/
static int Object_setAttr (BPy_Object *obj, char *name, PyObject *value)
{
PyObject * valtuple;
struct Object * object;
struct Ika * ika;
/* First put the value(s) in a tuple. For some variables, we want to */
/* pass the values to a function, and these functions only accept */
/* PyTuples. */
valtuple = Py_BuildValue ("(O)", value);
if (!valtuple)
{
return EXPP_ReturnIntError(PyExc_MemoryError,
"Object_setAttr: couldn't create PyTuple");
}
object = obj->object;
if (StringEqual (name, "LocX"))
return (!PyArg_Parse (value, "f", &(object->loc[0])));
if (StringEqual (name, "LocY"))
return (!PyArg_Parse (value, "f", &(object->loc[1])));
if (StringEqual (name, "LocZ"))
return (!PyArg_Parse (value, "f", &(object->loc[2])));
if (StringEqual (name, "loc"))
{
if (Object_setLocation (obj, valtuple) != Py_None)
return (-1);
else
return (0);
}
if (StringEqual (name, "dLocX"))
return (!PyArg_Parse (value, "f", &(object->dloc[0])));
if (StringEqual (name, "dLocY"))
return (!PyArg_Parse (value, "f", &(object->dloc[1])));
if (StringEqual (name, "dLocZ"))
return (!PyArg_Parse (value, "f", &(object->dloc[2])));
if (StringEqual (name, "dloc"))
{
if (Object_setDeltaLocation (obj, valtuple) != Py_None)
return (-1);
else
return (0);
}
if (StringEqual (name, "RotX"))
return (!PyArg_Parse (value, "f", &(object->rot[0])));
if (StringEqual (name, "RotY"))
return (!PyArg_Parse (value, "f", &(object->rot[1])));
if (StringEqual (name, "RotZ"))
return (!PyArg_Parse (value, "f", &(object->rot[2])));
if (StringEqual (name, "rot"))
{
if (Object_setEuler (obj, valtuple) != Py_None)
return (-1);
else
return (0);
}
if (StringEqual (name, "dRotX"))
return (!PyArg_Parse (value, "f", &(object->drot[0])));
if (StringEqual (name, "dRotY"))
return (!PyArg_Parse (value, "f", &(object->drot[1])));
if (StringEqual (name, "dRotZ"))
return (!PyArg_Parse (value, "f", &(object->drot[2])));
if (StringEqual (name, "drot"))
return (!PyArg_ParseTuple (value, "fff", &(object->drot[0]),
&(object->drot[1]), &(object->drot[2])));
if (StringEqual (name, "SizeX"))
return (!PyArg_Parse (value, "f", &(object->size[0])));
if (StringEqual (name, "SizeY"))
return (!PyArg_Parse (value, "f", &(object->size[1])));
if (StringEqual (name, "SizeZ"))
return (!PyArg_Parse (value, "f", &(object->size[2])));
if (StringEqual (name, "size"))
return (!PyArg_ParseTuple (value, "fff", &(object->size[0]),
&(object->size[1]), &(object->size[2])));
if (StringEqual (name, "dSizeX"))
return (!PyArg_Parse (value, "f", &(object->dsize[0])));
if (StringEqual (name, "dSizeY"))
return (!PyArg_Parse (value, "f", &(object->dsize[1])));
if (StringEqual (name, "dSizeZ"))
return (!PyArg_Parse (value, "f", &(object->dsize[2])));
if (StringEqual (name, "dsize"))
return (!PyArg_ParseTuple (value, "fff", &(object->dsize[0]),
&(object->dsize[1]), &(object->dsize[2])));
if (strncmp (name,"Eff", 3) == 0)
{
if ( (object->type == OB_IKA) && (object->data != NULL) )
{
ika = object->data;
switch (name[3])
{
case 'X':
return (!PyArg_Parse (value, "f", &(ika->effg[0])));
case 'Y':
return (!PyArg_Parse (value, "f", &(ika->effg[1])));
case 'Z':
return (!PyArg_Parse (value, "f", &(ika->effg[2])));
default:
/* Do we need to display a sensible error message here? */
return (0);
}
}
return (0);
}
if (StringEqual (name, "Layer"))
{
/* usage note: caller of this func needs to do a
Blender.Redraw(-1) to update and redraw the interface */
Base *base;
int newLayer;
int local;
if(PyArg_Parse (value, "i", &newLayer)){
/* uppper 2 bytes are for local view */
newLayer &= 0x00FFFFFF;
if( newLayer == 0 ) /* bail if nothing to do */
return( 0 );
/* update any bases pointing to our object */
base = FIRSTBASE;
if( base->object == obj->object ){
local = base->lay &= 0xFF000000;
base->lay = local | newLayer;
object->lay = base->lay;
}
countall();
}
else{
return EXPP_ReturnIntError(PyExc_AttributeError,
"expected int as bitmask");
}
return( 0 );
}
if (StringEqual (name, "parent"))
{
/* This is not allowed. */
EXPP_ReturnPyObjError (PyExc_AttributeError,
"Setting the parent is not allowed.");
return (0);
}
if (StringEqual (name, "track"))
{
if (Object_makeTrack (obj, valtuple) != Py_None)
return (-1);
else
return (0);
}
if (StringEqual (name, "data"))
{
/* This is not allowed. */
EXPP_ReturnPyObjError (PyExc_AttributeError,
"Setting the data is not allowed.");
return (0);
}
if (StringEqual (name, "ipo"))
{
/* This is not allowed. */
EXPP_ReturnPyObjError (PyExc_AttributeError,
"Setting the ipo is not allowed.");
return (0);
}
if (StringEqual (name, "mat"))
{
/* This is not allowed. */
EXPP_ReturnPyObjError (PyExc_AttributeError,
"Setting the matrix is not allowed.");
return (0);
}
if (StringEqual (name, "matrix"))
{
/* This is not allowed. */
EXPP_ReturnPyObjError (PyExc_AttributeError,
"Please use .setMatrix(matrix)");
return (0);
}
if (StringEqual (name, "colbits"))
return (!PyArg_Parse (value, "h", &(object->colbits)));
if (StringEqual (name, "drawType"))
{
if (Object_setDrawType (obj, valtuple) != Py_None)
return (-1);
else
return (0);
}
if (StringEqual (name, "drawMode"))
{
if (Object_setDrawMode (obj, valtuple) != Py_None)
return (-1);
else
return (0);
}
if (StringEqual (name, "name"))
{
if (Object_setName (obj, valtuple) != Py_None)
return (-1);
else
return (0);
}
if (StringEqual (name, "sel"))
{
if (Object_Select (obj, valtuple) != Py_None)
return (-1);
else
return (0);
}
printf ("Unknown variable.\n");
return (0);
}
/*****************************************************************************/
/* Function: Object_compare */
/* Description: This is a callback function for the BPy_Object type. It */
/* compares two Object_Type objects. Only the "==" and "!=" */
/* comparisons are meaninful. Returns 0 for equality and -1 if */
/* they don't point to the same Blender Object struct. */
/* In Python it becomes 1 if they are equal, 0 otherwise. */
/*****************************************************************************/
static int Object_compare (BPy_Object *a, BPy_Object *b)
{
Object *pa = a->object, *pb = b->object;
return (pa == pb) ? 0:-1;
}
/*****************************************************************************/
/* Function: Object_repr */
/* Description: This is a callback function for the BPy_Object type. It */
/* builds a meaninful string to represent object objects. */
/*****************************************************************************/
static PyObject *Object_repr (BPy_Object *self)
{
return PyString_FromFormat("[Object \"%s\"]", self->object->id.name+2);
}