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 9282827720 New scripts:
- hotkeys, obdatacopier and renameobjectbyblock, all from Jean-Michel Soler (jms);
- bevel_center by Loic Berthe, suggested for inclusion by jms;
- doc_browser, by Daniel Dunbar (Zr)

  Thanks to them for the new contributions!

  (I included doc_browser at 'Misc' because only users interested in script writing would actually use it, but it could also be under 'Help'.  Opinions?)

BPython related:
- Added scriptlink methods to object, lamp, camera and world.
- Object: added object.makeTrack and object.clearTrack (old track method).
- sys: made sys.exists(path) return 0 for not found; 1 for file, 2 for dir and -1 for neither.
- doc updates and fixes.
- made ONLOAD event work.  G.f's SCENESCRIPT bit was being zeroed in set_app_data.
- Blender: updated functions Load and Save to support the builtin importers and exporters besides .blend (dxf, videoscape, vrml 1.0, stl, ...)
- Draw: added mouse wheel events.
- Scene: added scene.play to play back animations (like ALT+A and SHIFT+ALT+A).  Makes a good counter, too, when the 'win' attribute is set to a space that doesn't "animate".

The scene.play() addition and the fix to ONLOAD scriptlinks is part of the work for a Blender demo mode.  It already works, but I'll still add support for Radiosity calculations and fix a thing in main(): it executes onload scripts too early (BIF_Init), giving funny results in alt+a animations and renderings when firing up Blender.  Loading after the program is up has no such problems.  When I finish I'll post examples of demo mode scripts.
2004-07-03 05:17:04 +00:00

2432 lines
70 KiB
C

/*
*
* ***** 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);
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_NOARGS,
"Returns list of materials assigned to the object"},
{"getMatrix", (PyCFunction)Object_getMatrix, METH_VARARGS,
"Returns the object matrix - worlspace or localspace (default)"},
{"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)
{
return (EXPP_PyList_fromMaterialList (self->object->mat,
self->object->totcol));
}
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 */
where_is_object(self->object);
Mat4CpyMat4(*((MatrixObject*)matrix)->matrix, self->object->obmat);
} else if (BLI_streq(space, "localspace")) { /* Localspace matrix*/
object_to_mat4(self->object, *((MatrixObject*)matrix)->matrix);
} else {
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
"correct spaces are 'worldspace' and 'localspace', none defaults to localespace"));
}
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);
}
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,
"illegal material index!"));
}
if (self->object->mat)
{
EXPP_releaseMaterialList (self->object->mat, len);
}
/* Increase the user count on all materials */
for (i=0 ; i<len ; i++)
{
id_us_plus ((ID *) matlist[i]);
}
self->object->mat = matlist;
self->object->totcol = len;
self->object->actcol = -1;
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,
self->object->data);
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_AttributeError,
"expected an object argument");
}
if (!Object_CheckPyObject ((PyObject*)object))
{
return EXPP_ReturnPyObjError (PyExc_TypeError,
"argument 1 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);
}
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;
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);
}