5b59449c8ea3f7e8ef87a14b0e16929c3eedc324
[blender.git] / source / blender / python / api2_2x / Object.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  *
27  * The Object module provides generic access to Objects of various types via
28  * the Python interface.
29  *
30  *
31  * Contributor(s): Michel Selten, Willian Germano, Jacques Guignot,
32  * Joseph Gilbert, Stephen Swaney, Bala Gi, Campbell Barton
33  *
34  * ***** END GPL/BL DUAL LICENSE BLOCK *****
35 */
36
37 #include "Object.h"
38 #include "NLA.h"
39 #include "logic.h"
40 #include <blendef.h>
41 #include <DNA_scene_types.h>
42 #include <DNA_mesh_types.h>
43 #include <DNA_curve_types.h>
44 #include <DNA_property_types.h>
45 #include <BSE_edit.h>
46 #include <BKE_property.h>
47 #include <BKE_mball.h>
48 #include <BIF_editview.h>
49
50 #include "Ipo.h"
51 #include "Lattice.h"
52 #include "modules.h"
53
54 /* only used for oops location get/set at the moment */
55 #include "DNA_oops_types.h" 
56 #include "DNA_space_types.h"
57
58 /*****************************************************************************/
59 /* Python API function prototypes for the Blender module.                */
60 /*****************************************************************************/
61 static PyObject *M_Object_New( PyObject * self, PyObject * args );
62 PyObject *M_Object_Get( PyObject * self, PyObject * args );
63 static PyObject *M_Object_GetSelected( PyObject * self, PyObject * args );
64
65 /*****************************************************************************/
66 /* The following string definitions are used for documentation strings.  */
67 /* In Python these will be written to the console when doing a           */
68 /* Blender.Object.__doc__                                                */
69 /*****************************************************************************/
70 char M_Object_doc[] = "The Blender Object module\n\n\
71 This module provides access to **Object Data** in Blender.\n";
72
73 char M_Object_New_doc[] =
74         "(type) - Add a new object of type 'type' in the current scene";
75
76 char M_Object_Get_doc[] =
77         "(name) - return the object with the name 'name', returns None if not\
78         found.\n\
79         If 'name' is not specified, it returns a list of all objects in the\n\
80         current scene.";
81
82 char M_Object_GetSelected_doc[] =
83         "() - Returns a list of selected Objects in the active layer(s)\n\
84 The active object is the first in the list, if visible";
85
86 /*****************************************************************************/
87 /* Python method structure definition for Blender.Object module:         */
88 /*****************************************************************************/
89 struct PyMethodDef M_Object_methods[] = {
90         {"New", ( PyCFunction ) M_Object_New, METH_VARARGS,
91          M_Object_New_doc},
92         {"Get", ( PyCFunction ) M_Object_Get, METH_VARARGS,
93          M_Object_Get_doc},
94         {"GetSelected", ( PyCFunction ) M_Object_GetSelected, METH_VARARGS,
95          M_Object_GetSelected_doc},
96         {NULL, NULL, 0, NULL}
97 };
98
99 /*****************************************************************************/
100 /* Python BPy_Object methods declarations:                                 */
101 /*****************************************************************************/
102 static PyObject *Object_buildParts( BPy_Object * self );
103 static PyObject *Object_clearIpo( BPy_Object * self );
104 static PyObject *Object_clrParent( BPy_Object * self, PyObject * args );
105 static PyObject *Object_clearTrack( BPy_Object * self, PyObject * args );
106 static PyObject *Object_getData(BPy_Object *self, PyObject *a, PyObject *kwd);
107 static PyObject *Object_getDeltaLocation( BPy_Object * self );
108 static PyObject *Object_getDrawMode( BPy_Object * self );
109 static PyObject *Object_getDrawType( BPy_Object * self );
110 static PyObject *Object_getEuler( BPy_Object * self );
111 static PyObject *Object_getInverseMatrix( BPy_Object * self );
112 static PyObject *Object_getIpo( BPy_Object * self );
113 static PyObject *Object_getLocation( BPy_Object * self, PyObject * args );
114 static PyObject *Object_getMaterials( BPy_Object * self, PyObject * args );
115 static PyObject *Object_getMatrix( BPy_Object * self, PyObject * args );
116 static PyObject *Object_getName( BPy_Object * self );
117 static PyObject *Object_getParent( BPy_Object * self );
118 static PyObject *Object_getSize( BPy_Object * self, PyObject * args );
119 static PyObject *Object_getTimeOffset( BPy_Object * self );
120 static PyObject *Object_getTracked( BPy_Object * self );
121 static PyObject *Object_getType( BPy_Object * self );
122 static PyObject *Object_getBoundBox( BPy_Object * self );
123 static PyObject *Object_getAction( BPy_Object * self );
124 static PyObject *Object_isSelected( BPy_Object * self );
125 static PyObject *Object_makeDisplayList( BPy_Object * self );
126 static PyObject *Object_link( BPy_Object * self, PyObject * args );
127 static PyObject *Object_makeParent( BPy_Object * self, PyObject * args );
128 static PyObject *Object_materialUsage( BPy_Object * self, PyObject * args );
129 static PyObject *Object_setDeltaLocation( BPy_Object * self, PyObject * args );
130 static PyObject *Object_setDrawMode( BPy_Object * self, PyObject * args );
131 static PyObject *Object_setDrawType( BPy_Object * self, PyObject * args );
132 static PyObject *Object_setEuler( BPy_Object * self, PyObject * args );
133 static PyObject *Object_setMatrix( BPy_Object * self, PyObject * args );
134 static PyObject *Object_setIpo( BPy_Object * self, PyObject * args );
135 static PyObject *Object_setLocation( BPy_Object * self, PyObject * args );
136 static PyObject *Object_setMaterials( BPy_Object * self, PyObject * args );
137 static PyObject *Object_setName( BPy_Object * self, PyObject * args );
138 static PyObject *Object_setSize( BPy_Object * self, PyObject * args );
139 static PyObject *Object_setTimeOffset( BPy_Object * self, PyObject * args );
140 static PyObject *Object_makeTrack( BPy_Object * self, PyObject * args );
141 static PyObject *Object_shareFrom( BPy_Object * self, PyObject * args );
142 static PyObject *Object_Select( BPy_Object * self, PyObject * args );
143 static PyObject *Object_getAllProperties( BPy_Object * self );
144 static PyObject *Object_addProperty( BPy_Object * self, PyObject * args );
145 static PyObject *Object_removeProperty( BPy_Object * self, PyObject * args );
146 static PyObject *Object_getProperty( BPy_Object * self, PyObject * args );
147 static PyObject *Object_removeAllProperties( BPy_Object * self );
148 static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
149                                              PyObject * args );
150 static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * args );
151 static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args );
152 static PyObject *Object_clearScriptLinks( BPy_Object * self );
153
154 /*****************************************************************************/
155 /* Python BPy_Object methods table:                                        */
156 /*****************************************************************************/
157 static PyMethodDef BPy_Object_methods[] = {
158         /* name, method, flags, doc */
159         {"buildParts", ( PyCFunction ) Object_buildParts, METH_NOARGS,
160          "Recalcs particle system (if any) "},
161         {"getIpo", ( PyCFunction ) Object_getIpo, METH_NOARGS,
162          "Returns the ipo of this object (if any) "},
163         {"clrParent", ( PyCFunction ) Object_clrParent, METH_VARARGS,
164          "Clears parent object. Optionally specify:\n\
165 mode\n\tnonzero: Keep object transform\nfast\n\t>0: Don't update scene \
166 hierarchy (faster)"},
167         {"clearTrack", ( PyCFunction ) Object_clearTrack, METH_VARARGS,
168          "Make this object not track another anymore. Optionally specify:\n\
169 mode\n\t2: Keep object transform\nfast\n\t>0: Don't update scene \
170 hierarchy (faster)"},
171         {"getData", ( PyCFunction ) Object_getData, METH_VARARGS | METH_KEYWORDS,
172          "(name_only = 0) - Returns the datablock object containing the object's \
173 data, e.g. Mesh.\n\
174 If 'name_only' is nonzero or True, only the name of the datablock is returned"},
175         {"getDeltaLocation", ( PyCFunction ) Object_getDeltaLocation,
176          METH_NOARGS,
177          "Returns the object's delta location (x, y, z)"},
178         {"getDrawMode", ( PyCFunction ) Object_getDrawMode, METH_NOARGS,
179          "Returns the object draw modes"},
180         {"getDrawType", ( PyCFunction ) Object_getDrawType, METH_NOARGS,
181          "Returns the object draw type"},
182         {"getAction", ( PyCFunction ) Object_getAction, METH_NOARGS,
183          "Returns the active action for this object"},
184         {"isSelected", ( PyCFunction ) Object_isSelected, METH_NOARGS,
185          "Return a 1 or 0 depending on whether the object is selected"},
186         {"getEuler", ( PyCFunction ) Object_getEuler, METH_NOARGS,
187          "Returns the object's rotation as Euler rotation vector\n\
188 (rotX, rotY, rotZ)"},
189         {"getInverseMatrix", ( PyCFunction ) Object_getInverseMatrix,
190          METH_NOARGS,
191          "Returns the object's inverse matrix"},
192         {"getLocation", ( PyCFunction ) Object_getLocation, METH_VARARGS,
193          "Returns the object's location (x, y, z)"},
194         {"getMaterials", ( PyCFunction ) Object_getMaterials, METH_VARARGS,
195          "(i = 0) - Returns list of materials assigned to the object.\n\
196 if i is nonzero, empty slots are not ignored: they are returned as None's."},
197         {"getMatrix", ( PyCFunction ) Object_getMatrix, METH_VARARGS,
198          "(str = 'worldspace') - Returns the object matrix.\n\
199 (str = 'worldspace') - the wanted matrix: worldspace (default), localspace\n\
200 or old_worldspace.\n\
201 \n\
202 'old_worldspace' was the only behavior before Blender 2.34.  With it the\n\
203 matrix is not updated for changes made by the script itself\n\
204 (like obj.LocX = 10) until a redraw happens, either called by the script or\n\
205 automatic when the script finishes."},
206         {"getName", ( PyCFunction ) Object_getName, METH_NOARGS,
207          "Returns the name of the object"},
208         {"getParent", ( PyCFunction ) Object_getParent, METH_NOARGS,
209          "Returns the object's parent object"},
210         {"getSize", ( PyCFunction ) Object_getSize, METH_VARARGS,
211          "Returns the object's size (x, y, z)"},
212         {"getTimeOffset", ( PyCFunction ) Object_getTimeOffset, METH_NOARGS,
213          "Returns the object's time offset"},
214         {"getTracked", ( PyCFunction ) Object_getTracked, METH_NOARGS,
215          "Returns the object's tracked object"},
216         {"getType", ( PyCFunction ) Object_getType, METH_NOARGS,
217          "Returns type of string of Object"},
218         {"getBoundBox", ( PyCFunction ) Object_getBoundBox, METH_NOARGS,
219          "Returns the object's bounding box"},
220         {"makeDisplayList", ( PyCFunction ) Object_makeDisplayList,
221          METH_NOARGS,
222          "Update this object's Display List. Some changes like turning \n\
223 'SubSurf' on for a mesh need this method (followed by a Redraw) to \n\
224 show the changes on the 3d window."},
225         {"link", ( PyCFunction ) Object_link, METH_VARARGS,
226          "Links Object with data provided in the argument. The data must \n\
227 match the Object's type, so you cannot link a Lamp to a Mesh type object."},
228         {"makeParent", ( PyCFunction ) Object_makeParent, METH_VARARGS,
229          "Makes the object the parent of the objects provided in the \n\
230 argument which must be a list of valid Objects. Optional extra arguments:\n\
231 mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
232 fast:\n\t0: update scene hierarchy automatically\n\t\
233 don't update scene hierarchy (faster). In this case, you must\n\t\
234 explicitely update the Scene hierarchy."},
235         {"materialUsage", ( PyCFunction ) Object_materialUsage, METH_VARARGS,
236          "Determines the way the material is used and returns status.\n\
237 Possible arguments (provide as strings):\n\
238 \tData:   Materials assigned to the object's data are shown. (default)\n\
239 \tObject: Materials assigned to the object are shown."},
240         {"setDeltaLocation", ( PyCFunction ) Object_setDeltaLocation,
241          METH_VARARGS,
242          "Sets the object's delta location which must be a vector triple."},
243         {"setDrawMode", ( PyCFunction ) Object_setDrawMode, METH_VARARGS,
244          "Sets the object's drawing mode. The argument can be a sum of:\n\
245 2:      axis\n4:  texspace\n8:  drawname\n16: drawimage\n32: drawwire"},
246         {"setDrawType", ( PyCFunction ) Object_setDrawType, METH_VARARGS,
247          "Sets the object's drawing type. The argument must be one of:\n\
248 1: Bounding box\n2: Wire\n3: Solid\n4: Shaded\n5: Textured"},
249         {"setEuler", ( PyCFunction ) Object_setEuler, METH_VARARGS,
250          "Set the object's rotation according to the specified Euler\n\
251 angles. The argument must be a vector triple"},
252         {"setMatrix", ( PyCFunction ) Object_setMatrix, METH_VARARGS,
253          "Set and apply a new matrix for the object"},
254         {"setLocation", ( PyCFunction ) Object_setLocation, METH_VARARGS,
255          "Set the object's location. The first argument must be a vector\n\
256 triple."},
257         {"setMaterials", ( PyCFunction ) Object_setMaterials, METH_VARARGS,
258          "Sets materials. The argument must be a list of valid material\n\
259 objects."},
260         {"setName", ( PyCFunction ) Object_setName, METH_VARARGS,
261          "Sets the name of the object"},
262         {"setSize", ( PyCFunction ) Object_setSize, METH_VARARGS,
263          "Set the object's size. The first argument must be a vector\n\
264 triple."},
265         {"setTimeOffset", ( PyCFunction ) Object_setTimeOffset, METH_VARARGS,
266          "Set the object's time offset."},
267         {"makeTrack", ( PyCFunction ) Object_makeTrack, METH_VARARGS,
268          "(trackedobj, fast = 0) - Make this object track another.\n\
269          (trackedobj) - the object that will be tracked.\n\
270          (fast = 0) - if 0: update the scene hierarchy automatically.  If you\n\
271          set 'fast' to a nonzero value, don't forget to update the scene yourself\n\
272          (see scene.update())."},
273         {"shareFrom", ( PyCFunction ) Object_shareFrom, METH_VARARGS,
274          "Link data of self with object specified in the argument. This\n\
275 works only if self and the object specified are of the same type."},
276         {"select", ( PyCFunction ) Object_Select, METH_VARARGS,
277          "( 1 or 0 )  - Set the selected state of the object.\n\
278    1 is selected, 0 not selected "},
279         {"setIpo", ( PyCFunction ) Object_setIpo, METH_VARARGS,
280          "(Blender Ipo) - Sets the object's ipo"},
281         {"clearIpo", ( PyCFunction ) Object_clearIpo, METH_NOARGS,
282          "() - Unlink ipo from this object"},
283         {"getAllProperties", ( PyCFunction ) Object_getAllProperties,
284          METH_NOARGS,
285          "() - Get all the properties from this object"},
286         {"addProperty", ( PyCFunction ) Object_addProperty, METH_VARARGS,
287          "() - Add a property to this object"},
288         {"removeProperty", ( PyCFunction ) Object_removeProperty, METH_VARARGS,
289          "() - Remove a property from  this object"},
290         {"getProperty", ( PyCFunction ) Object_getProperty, METH_VARARGS,
291          "() - Get a property from this object by name"},
292         {"removeAllProperties", ( PyCFunction ) Object_removeAllProperties,
293          METH_NOARGS,
294          "() - removeAll a properties from this object"},
295         {"copyAllPropertiesTo", ( PyCFunction ) Object_copyAllPropertiesTo,
296          METH_VARARGS,
297          "() - copy all properties from this object to another object"},
298         {"getScriptLinks", ( PyCFunction ) Object_getScriptLinks, METH_VARARGS,
299          "(eventname) - Get a list of this object's scriptlinks (Text names) "
300          "of the given type\n"
301          "(eventname) - string: FrameChanged or Redraw."},
302         {"addScriptLink", ( PyCFunction ) Object_addScriptLink, METH_VARARGS,
303          "(text, evt) - Add a new object scriptlink.\n"
304          "(text) - string: an existing Blender Text name;\n"
305          "(evt) string: FrameChanged or Redraw."},
306         {"clearScriptLinks", ( PyCFunction ) Object_clearScriptLinks,
307          METH_NOARGS,
308          "() - Delete all scriptlinks from this object."},
309         {NULL, NULL, 0, NULL}
310 };
311
312 /*****************************************************************************/
313 /* PythonTypeObject callback function prototypes                         */
314 /*****************************************************************************/
315 static void Object_dealloc( BPy_Object * obj );
316 static PyObject *Object_getAttr( BPy_Object * obj, char *name );
317 static int Object_setAttr( BPy_Object * obj, char *name, PyObject * v );
318 static PyObject *Object_repr( BPy_Object * obj );
319 static int Object_compare( BPy_Object * a, BPy_Object * b );
320
321 /*****************************************************************************/
322 /* Python TypeObject structure definition.                               */
323 /*****************************************************************************/
324 PyTypeObject Object_Type = {
325         PyObject_HEAD_INIT( NULL ) /* requred macro */
326         0,      /* ob_size */
327         "Blender Object",       /* tp_name */
328         sizeof( BPy_Object ),   /* tp_basicsize */
329         0,                      /* tp_itemsize */
330         /* methods */
331         ( destructor ) Object_dealloc,  /* tp_dealloc */
332         0,                      /* tp_print */
333         ( getattrfunc ) Object_getAttr, /* tp_getattr */
334         ( setattrfunc ) Object_setAttr, /* tp_setattr */
335         ( cmpfunc ) Object_compare,     /* tp_compare */
336         ( reprfunc ) Object_repr,       /* tp_repr */
337         0,                      /* tp_as_number */
338         0,                      /* tp_as_sequence */
339         0,                      /* tp_as_mapping */
340         0,                      /* tp_as_hash */
341         0, 0, 0, 0, 0, 0,
342         0,                      /* tp_doc */
343         0, 0, 0, 0, 0, 0,
344         BPy_Object_methods,     /* tp_methods */
345         0,                      /* tp_members */
346         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
347 };
348
349 /*****************************************************************************/
350 /* Function:                      M_Object_New                           */
351 /* Python equivalent:     Blender.Object.New                             */
352 /*****************************************************************************/
353 PyObject *M_Object_New( PyObject * self, PyObject * args )
354 {
355         struct Object *object;
356         BPy_Object *blen_object;
357         int type;
358         char *str_type;
359         char *name = NULL;
360
361         if( !PyArg_ParseTuple( args, "s|s", &str_type, &name ) ) {
362                 EXPP_ReturnPyObjError( PyExc_TypeError,
363                                        "string expected as argument" );
364                 return ( NULL );
365         }
366
367         if( strcmp( str_type, "Armature" ) == 0 )
368                 type = OB_ARMATURE;
369         else if( strcmp( str_type, "Camera" ) == 0 )
370                 type = OB_CAMERA;
371         else if( strcmp( str_type, "Curve" ) == 0 )
372                 type = OB_CURVE;
373 /*      else if (strcmp (str_type, "Text") == 0)        type = OB_FONT; */
374 /*      else if (strcmp (str_type, "Ika") == 0)         type = OB_IKA; */
375         else if( strcmp( str_type, "Lamp" ) == 0 )
376                 type = OB_LAMP;
377         else if( strcmp( str_type, "Lattice" ) == 0 )
378                 type = OB_LATTICE;
379         else if( strcmp( str_type, "Mball" ) == 0 )
380                 type = OB_MBALL;
381         else if( strcmp( str_type, "Mesh" ) == 0 )
382                 type = OB_MESH;
383         else if( strcmp( str_type, "Surf" ) == 0 )
384                 type = OB_SURF;
385 /*      else if (strcmp (str_type, "Wave") == 0)        type = OB_WAVE; */
386         else if( strcmp( str_type, "Empty" ) == 0 )
387                 type = OB_EMPTY;
388         else {
389                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
390                                                 "Unknown type specified" ) );
391         }
392
393         /* Create a new object. */
394         if( name == NULL ) {
395         /* No name is specified, set the name to the type of the object. */
396                 name = str_type;
397         }
398         object = alloc_libblock( &( G.main->object ), ID_OB, name );
399
400         object->id.us = 0;
401         object->flag = 0;
402         object->type = type;
403
404
405         /* transforms */
406         QuatOne( object->quat );
407         QuatOne( object->dquat );
408
409         object->col[3] = 1.0;   // alpha 
410
411         object->size[0] = object->size[1] = object->size[2] = 1.0;
412         object->loc[0] = object->loc[1] = object->loc[2] = 0.0;
413         Mat4One( object->parentinv );
414         Mat4One( object->obmat );
415         object->dt = OB_SHADED; // drawtype
416
417         if( U.flag & USER_MAT_ON_OB ) {
418                 object->colbits = -1;
419         }
420         switch ( object->type ) {
421         case OB_CAMERA: /* fall through. */
422         case OB_LAMP:
423                 object->trackflag = OB_NEGZ;
424                 object->upflag = OB_POSY;
425                 break;
426         default:
427                 object->trackflag = OB_POSY;
428                 object->upflag = OB_POSZ;
429         }
430         object->ipoflag = OB_OFFS_OB + OB_OFFS_PARENT;
431
432         /* duplivert settings */
433         object->dupon = 1;
434         object->dupoff = 0;
435         object->dupsta = 1;
436         object->dupend = 100;
437
438         /* Gameengine defaults */
439         object->mass = 1.0;
440         object->inertia = 1.0;
441         object->formfactor = 0.4;
442         object->damping = 0.04;
443         object->rdamping = 0.1;
444         object->anisotropicFriction[0] = 1.0;
445         object->anisotropicFriction[1] = 1.0;
446         object->anisotropicFriction[2] = 1.0;
447         object->gameflag = OB_PROP;
448
449         object->lay = 1;        // Layer, by default visible
450         G.totobj++;
451
452         object->data = NULL;
453
454         /* Create a Python object from it. */
455         blen_object =
456                 ( BPy_Object * ) PyObject_NEW( BPy_Object, &Object_Type );
457         blen_object->object = object;
458
459         return ( ( PyObject * ) blen_object );
460 }
461
462 /*****************************************************************************/
463 /* Function:      M_Object_Get                                          */
464 /* Python equivalent:     Blender.Object.Get                            */
465 /*****************************************************************************/
466 PyObject *M_Object_Get( PyObject * self, PyObject * args )
467 {
468         struct Object *object;
469         BPy_Object *blen_object;
470         char *name = NULL;
471
472         PyArg_ParseTuple( args, "|s", &name );
473
474         if( name != NULL ) {
475                 object = GetObjectByName( name );
476
477                 if( object == NULL ) {
478                         /* No object exists with the name specified in the argument name. */
479                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
480                                                         "Unknown object specified." ) );
481                 }
482                 blen_object =
483                         ( BPy_Object * ) PyObject_NEW( BPy_Object,
484                                                        &Object_Type );
485                 blen_object->object = object;
486
487                 return ( ( PyObject * ) blen_object );
488         } else {
489                 /* No argument has been given. Return a list of all objects. */
490                 PyObject *obj_list;
491                 Link *link;
492                 int index;
493
494                 obj_list = PyList_New( BLI_countlist( &( G.main->object ) ) );
495
496                 if( obj_list == NULL ) {
497                         return ( EXPP_ReturnPyObjError( PyExc_SystemError,
498                                                         "List creation failed." ) );
499                 }
500
501                 link = G.main->object.first;
502                 index = 0;
503                 while( link ) {
504                         object = ( Object * ) link;
505                         blen_object =
506                                 ( BPy_Object * ) PyObject_NEW( BPy_Object,
507                                                                &Object_Type );
508                         blen_object->object = object;
509
510                         PyList_SetItem( obj_list, index,
511                                         ( PyObject * ) blen_object );
512                         index++;
513                         link = link->next;
514                 }
515                 return ( obj_list );
516         }
517 }
518
519 /*****************************************************************************/
520 /* Function:      M_Object_GetSelected                          */
521 /* Python equivalent:     Blender.Object.GetSelected            */
522 /*****************************************************************************/
523 static PyObject *M_Object_GetSelected( PyObject * self, PyObject * args )
524 {
525         BPy_Object *blen_object;
526         PyObject *list;
527         Base *base_iter;
528
529         if( G.vd == NULL ) {
530                 // No 3d view has been initialized yet, simply return None
531                 Py_INCREF( Py_None );
532                 return Py_None;
533         }
534         list = PyList_New( 0 );
535         if( ( G.scene->basact ) &&
536             ( ( G.scene->basact->flag & SELECT ) &&
537               ( G.scene->basact->lay & G.vd->lay ) ) ) {
538                 /* Active object is first in the list. */
539                 blen_object =
540                         ( BPy_Object * ) PyObject_NEW( BPy_Object,
541                                                        &Object_Type );
542                 if( blen_object == NULL ) {
543                         Py_DECREF( list );
544                         Py_INCREF( Py_None );
545                         return ( Py_None );
546                 }
547                 blen_object->object = G.scene->basact->object;
548                 PyList_Append( list, ( PyObject * ) blen_object );
549                 Py_DECREF( blen_object );
550         }
551
552         base_iter = G.scene->base.first;
553         while( base_iter ) {
554                 if( ( ( base_iter->flag & SELECT ) &&
555                       ( base_iter->lay & G.vd->lay ) ) &&
556                     ( base_iter != G.scene->basact ) ) {
557                         blen_object =
558                                 ( BPy_Object * ) PyObject_NEW( BPy_Object,
559                                                                &Object_Type );
560                         if( blen_object == NULL ) {
561                                 Py_DECREF( list );
562                                 Py_INCREF( Py_None );
563                                 return ( Py_None );
564                         }
565                         blen_object->object = base_iter->object;
566                         PyList_Append( list, ( PyObject * ) blen_object );
567                         Py_DECREF( blen_object );
568                 }
569                 base_iter = base_iter->next;
570         }
571         return ( list );
572 }
573
574 /*****************************************************************************/
575 /* Function:     initObject                                             */
576 /*****************************************************************************/
577 PyObject *Object_Init( void )
578 {
579         PyObject *module;
580
581         Object_Type.ob_type = &PyType_Type;
582
583         module = Py_InitModule3( "Blender.Object", M_Object_methods,
584                                  M_Object_doc );
585
586         return ( module );
587 }
588
589 /*****************************************************************************/
590 /* Python BPy_Object methods:                                   */
591 /*****************************************************************************/
592
593 static PyObject *Object_buildParts( BPy_Object * self )
594 {
595         void build_particle_system( Object * ob );
596         struct Object *obj = self->object;
597
598         build_particle_system( obj );
599
600         Py_INCREF( Py_None );
601         return ( Py_None );
602 }
603
604 static PyObject *Object_clearIpo( BPy_Object * self )
605 {
606         Object *ob = self->object;
607         Ipo *ipo = ( Ipo * ) ob->ipo;
608
609         if( ipo ) {
610                 ID *id = &ipo->id;
611                 if( id->us > 0 )
612                         id->us--;
613                 ob->ipo = NULL;
614
615                 return EXPP_incr_ret_True();
616         }
617
618         return EXPP_incr_ret_False(); /* no ipo found */
619 }
620
621 static PyObject *Object_clrParent( BPy_Object * self, PyObject * args )
622 {
623         int mode = 0;
624         int fast = 0;
625
626         if( !PyArg_ParseTuple( args, "|ii", &mode, &fast ) ) {
627                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
628                                                 "expected one or two integers as arguments" ) );
629         }
630
631         /* Remove the link only, the object is still in the scene. */
632         self->object->parent = NULL;
633
634         if( mode == 2 ) {
635                 /* Keep transform */
636                 apply_obmat( self->object );
637         }
638
639         if( !fast ) {
640                 sort_baselist( G.scene );
641         }
642
643         Py_INCREF( Py_None );
644         return ( Py_None );
645 }
646
647 static PyObject *Object_clearTrack( BPy_Object * self, PyObject * args )
648 {
649         int mode = 0;
650         int fast = 0;
651
652         if( !PyArg_ParseTuple( args, "|ii", &mode, &fast ) ) {
653                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
654                                                 "expected one or two integers as arguments" ) );
655         }
656
657         /* Remove the link only, the object is still in the scene. */
658         self->object->track = NULL;
659
660         if( mode ) {
661                 /* Keep transform */
662                 apply_obmat( self->object );
663         }
664
665         if( !fast ) {
666                 sort_baselist( G.scene );
667         }
668
669         Py_INCREF( Py_None );
670         return ( Py_None );
671 }
672
673 /* adds object data to a Blender object, if object->data = NULL */
674 int EXPP_add_obdata( struct Object *object )
675 {
676         if( object->data != NULL )
677                 return -1;
678
679         switch ( object->type ) {
680         case OB_ARMATURE:
681                 /* TODO: Do we need to add something to G? (see the OB_LAMP case) */
682                 object->data = add_armature(  );
683                 break;
684         case OB_CAMERA:
685                 /* TODO: Do we need to add something to G? (see the OB_LAMP case) */
686                 object->data = add_camera(  );
687                 break;
688         case OB_CURVE:
689                 object->data = add_curve( OB_CURVE );
690                 G.totcurve++;
691                 break;
692         case OB_LAMP:
693                 object->data = add_lamp(  );
694                 G.totlamp++;
695                 break;
696         case OB_MESH:
697                 object->data = add_mesh(  );
698                 G.totmesh++;
699                 break;
700         case OB_LATTICE:
701                 object->data = ( void * ) add_lattice(  );
702                 object->dt = OB_WIRE;
703                 break;
704         case OB_MBALL:
705                 object->data = add_mball(  );
706                 break;
707
708                 /* TODO the following types will be supported later
709                    case OB_SURF:
710                    object->data = add_curve(OB_SURF);
711                    G.totcurve++;
712                    break;
713                    case OB_FONT:
714                    object->data = add_curve(OB_FONT);
715                    break;
716                    case OB_IKA:
717                    object->data = add_ika();
718                    object->dt = OB_WIRE;
719                    break;
720                    case OB_WAVE:
721                    object->data = add_wave();
722                    break;
723                  */
724         default:
725                 break;
726         }
727
728         if( !object->data )
729                 return -1;
730
731         return 0;
732 }
733
734
735 static PyObject *Object_getData( BPy_Object *self, PyObject *a, PyObject *kwd )
736 {
737         PyObject *data_object;
738         Object *object = self->object;
739         int name_only = 0;
740         static char *kwlist[] = {"name_only", NULL};
741
742         if (!PyArg_ParseTupleAndKeywords(a, kwd, "|i", kwlist, &name_only))
743                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
744                         "expected nothing or an int (keyword 'name_only') as argument" );
745
746         /* if there's no obdata, try to create it */
747         if( object->data == NULL ) {
748                 if( EXPP_add_obdata( object ) != 0 ) {  /* couldn't create obdata */
749                         Py_INCREF( Py_None );
750                         return ( Py_None );
751                 }
752         }
753
754         /* user wants only the name of the data object */
755         if (name_only) {
756                 ID *id = object->data;
757                 data_object = Py_BuildValue("s", id->name+2);
758
759                 if (data_object) return data_object;
760                 return EXPP_ReturnPyObjError (PyExc_MemoryError,
761                         "could not create a string pyobject!");
762         }
763
764         /* user wants the data object wrapper */
765         data_object = NULL;
766
767         switch ( object->type ) {
768         case OB_ARMATURE:
769                 data_object = Armature_CreatePyObject( object->data );
770                 break;
771         case OB_CAMERA:
772                 data_object = Camera_CreatePyObject( object->data );
773                 break;
774         case OB_CURVE:
775                 data_object = Curve_CreatePyObject( object->data );
776                 break;
777         case ID_IM:
778                 data_object = Image_CreatePyObject( object->data );
779                 break;
780         case ID_IP:
781                 data_object = Ipo_CreatePyObject( object->data );
782                 break;
783         case OB_LAMP:
784                 data_object = Lamp_CreatePyObject( object->data );
785                 break;
786         case OB_LATTICE:
787                 data_object = Lattice_CreatePyObject( object->data );
788                 break;
789         case ID_MA:
790                 break;
791         case OB_MESH:
792                 data_object = NMesh_CreatePyObject( object->data, object );
793                 break;
794         case ID_OB:
795                 data_object = Object_CreatePyObject( object->data );
796                 break;
797         case ID_SCE:
798                 break;
799         case ID_TXT:
800                 data_object = Text_CreatePyObject( object->data );
801                 break;
802         case ID_WO:
803                 break;
804         default:
805                 break;
806         }
807         if( data_object == NULL ) {
808                 Py_INCREF( Py_None );
809                 return ( Py_None );
810         } else {
811                 return ( data_object );
812         }
813 }
814
815 static PyObject *Object_getDeltaLocation( BPy_Object * self )
816 {
817         PyObject *attr = Py_BuildValue( "fff",
818                                         self->object->dloc[0],
819                                         self->object->dloc[1],
820                                         self->object->dloc[2] );
821
822         if( attr )
823                 return ( attr );
824
825         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
826                                         "couldn't get Object.dloc attributes" ) );
827 }
828
829 static PyObject *Object_getDrawMode( BPy_Object * self )
830 {
831         PyObject *attr = Py_BuildValue( "b", self->object->dtx );
832
833         if( attr )
834                 return ( attr );
835
836         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
837                                         "couldn't get Object.drawMode attribute" ) );
838 }
839
840 static PyObject *Object_getAction( BPy_Object * self )
841 {
842         /*BPy_Action *py_action = NULL; */
843
844         if( !self->object->action ) {
845                 Py_INCREF( Py_None );
846                 return ( Py_None );
847         } else {
848                 return Action_CreatePyObject( self->object->action );
849         }
850 }
851
852
853 static PyObject *Object_isSelected( BPy_Object * self )
854 {
855         Base *base;
856
857         base = FIRSTBASE;
858         while( base ) {
859                 if( base->object == self->object ) {
860                         if( base->flag & SELECT ) {
861                                 return EXPP_incr_ret_True();
862                         } else {
863                                 return EXPP_incr_ret_False();
864                         }
865                 }
866                 base = base->next;
867         }
868         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
869                                         "Internal error: could not find objects selection state" ) );
870 }
871
872
873 static PyObject *Object_getDrawType( BPy_Object * self )
874 {
875         PyObject *attr = Py_BuildValue( "b", self->object->dt );
876
877         if( attr )
878                 return ( attr );
879
880         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
881                                         "couldn't get Object.drawType attribute" ) );
882 }
883
884 static PyObject *Object_getEuler( BPy_Object * self )
885 {
886         EulerObject *eul;
887
888         eul = ( EulerObject * ) newEulerObject( NULL );
889         eul->eul[0] = self->object->rot[0];
890         eul->eul[1] = self->object->rot[1];
891         eul->eul[2] = self->object->rot[2];
892
893         return ( PyObject * ) eul;
894
895 }
896
897 static PyObject *Object_getInverseMatrix( BPy_Object * self )
898 {
899         MatrixObject *inverse =
900                 ( MatrixObject * ) newMatrixObject( NULL, 4, 4 );
901         Mat4Invert( *inverse->matrix, self->object->obmat );
902
903         return ( ( PyObject * ) inverse );
904 }
905
906 static PyObject *Object_getIpo( BPy_Object * self )
907 {
908         struct Ipo *ipo = self->object->ipo;
909
910         if( !ipo ) {
911                 Py_INCREF( Py_None );
912                 return Py_None;
913         }
914
915         return Ipo_CreatePyObject( ipo );
916 }
917
918 static PyObject *Object_getLocation( BPy_Object * self, PyObject * args )
919 {
920         PyObject *attr = Py_BuildValue( "fff",
921                                         self->object->loc[0],
922                                         self->object->loc[1],
923                                         self->object->loc[2] );
924
925         if( attr )
926                 return ( attr );
927
928         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
929                                         "couldn't get Object.loc attributes" ) );
930 }
931
932 static PyObject *Object_getMaterials( BPy_Object * self, PyObject * args )
933 {
934         int all = 0;
935
936         if( !PyArg_ParseTuple( args, "|i", &all ) ) {
937                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
938                                                 "expected an int or nothing" ) );
939         }
940
941         return ( EXPP_PyList_fromMaterialList( self->object->mat,
942                                                self->object->totcol, all ) );
943 }
944
945 static PyObject *Object_getMatrix( BPy_Object * self, PyObject * args )
946 {
947         PyObject *matrix;
948         char *space = "worldspace";     /* default to world */
949
950         if( !PyArg_ParseTuple( args, "|s", &space ) ) {
951                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
952                                                 "expected a string or nothing" ) );
953         }
954         //new matrix
955         matrix = newMatrixObject( NULL, 4, 4 );
956
957         if( BLI_streq( space, "worldspace" ) ) {        /* Worldspace matrix */
958                 disable_where_script( 1 );
959                 where_is_object( self->object );
960                 disable_where_script( 0 );
961                 Mat4CpyMat4( *( ( MatrixObject * ) matrix )->matrix,
962                              self->object->obmat );
963         } else if( BLI_streq( space, "localspace" ) ) { /* Localspace matrix */
964                 object_to_mat4( self->object,
965                                 *( ( MatrixObject * ) matrix )->matrix );
966                 /* old behavior, prior to 2.34, check this method's doc string: */
967         } else if( BLI_streq( space, "old_worldspace" ) ) {
968                 Mat4CpyMat4( *( ( MatrixObject * ) matrix )->matrix,
969                              self->object->obmat );
970         } else {
971                 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
972                                 "wrong parameter, expected nothing or either 'worldspace' (default),\n\
973 'localspace' or 'old_worldspace'" ) );
974         }
975         return matrix;
976 }
977
978 static PyObject *Object_getName( BPy_Object * self )
979 {
980         PyObject *attr = Py_BuildValue( "s", self->object->id.name + 2 );
981
982         if( attr )
983                 return ( attr );
984
985         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
986                                         "couldn't get the name of the Object" ) );
987 }
988
989 static PyObject *Object_getParent( BPy_Object * self )
990 {
991         PyObject *attr;
992
993         if( self->object->parent == NULL )
994                 return EXPP_incr_ret( Py_None );
995
996         attr = Object_CreatePyObject( self->object->parent );
997
998         if( attr ) {
999                 return ( attr );
1000         }
1001
1002         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1003                                         "couldn't get Object.parent attribute" ) );
1004 }
1005
1006 static PyObject *Object_getSize( BPy_Object * self, PyObject * args )
1007 {
1008         PyObject *attr = Py_BuildValue( "fff",
1009                                         self->object->size[0],
1010                                         self->object->size[1],
1011                                         self->object->size[2] );
1012
1013         if( attr )
1014                 return ( attr );
1015
1016         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1017                                         "couldn't get Object.size attributes" ) );
1018 }
1019
1020 static PyObject *Object_getTimeOffset( BPy_Object * self )
1021 {
1022         PyObject *attr = Py_BuildValue( "f", self->object->sf );
1023
1024         if( attr )
1025                 return ( attr );
1026
1027         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1028                                         "couldn't get Object.sf attributes" ) );
1029 }
1030
1031
1032 static PyObject *Object_getTracked( BPy_Object * self )
1033 {
1034         PyObject *attr;
1035
1036         if( self->object->track == NULL )
1037                 return EXPP_incr_ret( Py_None );
1038
1039         attr = Object_CreatePyObject( self->object->track );
1040
1041         if( attr ) {
1042                 return ( attr );
1043         }
1044
1045         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1046                                         "couldn't get Object.track attribute" ) );
1047 }
1048
1049 static PyObject *Object_getType( BPy_Object * self )
1050 {
1051         switch ( self->object->type ) {
1052         case OB_ARMATURE:
1053                 return ( Py_BuildValue( "s", "Armature" ) );
1054         case OB_CAMERA:
1055                 return ( Py_BuildValue( "s", "Camera" ) );
1056         case OB_CURVE:
1057                 return ( Py_BuildValue( "s", "Curve" ) );
1058         case OB_EMPTY:
1059                 return ( Py_BuildValue( "s", "Empty" ) );
1060         case OB_FONT:
1061                 return ( Py_BuildValue( "s", "Text" ) );
1062         case OB_IKA:
1063                 return ( Py_BuildValue( "s", "Ika" ) );
1064         case OB_LAMP:
1065                 return ( Py_BuildValue( "s", "Lamp" ) );
1066         case OB_LATTICE:
1067                 return ( Py_BuildValue( "s", "Lattice" ) );
1068         case OB_MBALL:
1069                 return ( Py_BuildValue( "s", "MBall" ) );
1070         case OB_MESH:
1071                 return ( Py_BuildValue( "s", "Mesh" ) );
1072         case OB_SURF:
1073                 return ( Py_BuildValue( "s", "Surf" ) );
1074         case OB_WAVE:
1075                 return ( Py_BuildValue( "s", "Wave" ) );
1076         default:
1077                 return ( Py_BuildValue( "s", "unknown" ) );
1078         }
1079 }
1080
1081
1082 static PyObject *Object_getBoundBox( BPy_Object * self )
1083 {
1084         int i;
1085         float *vec = NULL;
1086         PyObject *vector, *bbox;
1087
1088         if( !self->object->data )
1089                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1090                                               "This object isn't linked to any object data (mesh, curve, etc) yet" );
1091
1092         if( !self->object->bb ) {       /* if no ob bbox, we look in obdata */
1093                 Mesh *me;
1094                 Curve *curve;
1095                 switch ( self->object->type ) {
1096                 case OB_MESH:
1097                         me = self->object->data;
1098                         if( !me->bb )
1099                                 tex_space_mesh( me );
1100                         vec = ( float * ) me->bb->vec;
1101                         break;
1102                 case OB_CURVE:
1103                 case OB_FONT:
1104                 case OB_SURF:
1105                         curve = self->object->data;
1106                         if( !curve->bb )
1107                                 tex_space_curve( curve );
1108                         vec = ( float * ) curve->bb->vec;
1109                         break;
1110                 default:
1111                         Py_INCREF( Py_None );
1112                         return Py_None;
1113                 }
1114
1115                 {               /* transform our obdata bbox by the obmat.
1116                                    the obmat is 4x4 homogeneous coords matrix.
1117                                    each bbox coord is xyz, so we make it homogenous
1118                                    by padding it with w=1.0 and doing the matrix mult.
1119                                    afterwards we divide by w to get back to xyz.
1120                                  */
1121                         /* printmatrix4( "obmat", self->object->obmat); */
1122
1123                         float tmpvec[4];        /* tmp vector for homogenous coords math */
1124                         int i;
1125                         float *from;
1126
1127                         bbox = PyList_New( 8 );
1128                         if( !bbox )
1129                                 return EXPP_ReturnPyObjError
1130                                         ( PyExc_MemoryError,
1131                                           "couldn't create pylist" );
1132                         for( i = 0, from = vec; i < 8; i++, from += 3 ) {
1133                                 memcpy( tmpvec, from, 3 * sizeof( float ) );
1134                                 tmpvec[3] = 1.0f;       /* set w coord */
1135                                 Mat4MulVec4fl( self->object->obmat, tmpvec );
1136                                 /* divide x,y,z by w */
1137                                 tmpvec[0] /= tmpvec[3];
1138                                 tmpvec[1] /= tmpvec[3];
1139                                 tmpvec[2] /= tmpvec[3];
1140
1141 #if 0
1142                                 {       /* debug print stuff */
1143                                         int i;
1144
1145                                         printf( "\nobj bbox transformed\n" );
1146                                         for( i = 0; i < 4; ++i )
1147                                                 printf( "%f ", tmpvec[i] );
1148
1149                                         printf( "\n" );
1150                                 }
1151 #endif
1152
1153                                 /* because our bounding box is calculated and
1154                                    does not have its own memory,
1155                                    we must create vectors that allocate space */
1156
1157                                 vector = newVectorObject( NULL, 3 );
1158                                 memcpy( ( ( VectorObject * ) vector )->vec,
1159                                         tmpvec, 3 * sizeof( float ) );
1160                                 PyList_SET_ITEM( bbox, i, vector );
1161                         }
1162                 }
1163         } else {                /* the ob bbox exists */
1164                 vec = ( float * ) self->object->bb->vec;
1165
1166                 if( !vec )
1167                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1168                                                       "couldn't retrieve bounding box data" );
1169
1170                 bbox = PyList_New( 8 );
1171
1172                 if( !bbox )
1173                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1174                                                       "couldn't create pylist" );
1175
1176                 /* create vectors referencing object bounding box coords */
1177                 for( i = 0; i < 8; i++ ) {
1178                         vector = newVectorObject( vec, 3 );
1179                         PyList_SET_ITEM( bbox, i, vector );
1180                         vec += 3;
1181                 }
1182         }
1183
1184         return bbox;
1185 }
1186
1187
1188 static PyObject *Object_makeDisplayList( BPy_Object * self )
1189 {
1190         Object *ob = self->object;
1191
1192         if( ob->type == OB_FONT )
1193                 text_to_curve( ob, 0 );
1194
1195         makeDispList( ob );
1196
1197         Py_INCREF( Py_None );
1198         return Py_None;
1199 }
1200
1201 static PyObject *Object_link( BPy_Object * self, PyObject * args )
1202 {
1203         PyObject *py_data;
1204         ID *id;
1205         ID *oldid;
1206         int obj_id;
1207         void *data = NULL;
1208
1209         if( !PyArg_ParseTuple( args, "O", &py_data ) ) {
1210                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1211                                                 "expected an object as argument" ) );
1212         }
1213         if( Armature_CheckPyObject( py_data ) )
1214                 data = ( void * ) Armature_FromPyObject( py_data );
1215         if( Camera_CheckPyObject( py_data ) )
1216                 data = ( void * ) Camera_FromPyObject( py_data );
1217         if( Lamp_CheckPyObject( py_data ) )
1218                 data = ( void * ) Lamp_FromPyObject( py_data );
1219         if( Curve_CheckPyObject( py_data ) )
1220                 data = ( void * ) Curve_FromPyObject( py_data );
1221         if( NMesh_CheckPyObject( py_data ) )
1222                 data = ( void * ) Mesh_FromPyObject( py_data, self->object );
1223         if( Lattice_CheckPyObject( py_data ) )
1224                 data = ( void * ) Lattice_FromPyObject( py_data );
1225         if( Metaball_CheckPyObject( py_data ) )
1226                 data = ( void * ) Metaball_FromPyObject( py_data );
1227
1228         /* have we set data to something good? */
1229         if( !data ) {
1230                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1231                                                 "link argument type is not supported " ) );
1232         }
1233
1234         oldid = ( ID * ) self->object->data;
1235         id = ( ID * ) data;
1236         obj_id = MAKE_ID2( id->name[0], id->name[1] );
1237
1238         switch ( obj_id ) {
1239         case ID_AR:
1240                 if( self->object->type != OB_ARMATURE ) {
1241                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1242                                                         "The 'link' object is incompatible with the base object" ) );
1243                 }
1244                 break;
1245         case ID_CA:
1246                 if( self->object->type != OB_CAMERA ) {
1247                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1248                                                         "The 'link' object is incompatible with the base object" ) );
1249                 }
1250                 break;
1251         case ID_LA:
1252                 if( self->object->type != OB_LAMP ) {
1253                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1254                                                         "The 'link' object is incompatible with the base object" ) );
1255                 }
1256                 break;
1257         case ID_ME:
1258                 if( self->object->type != OB_MESH ) {
1259                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1260                                                         "The 'link' object is incompatible with the base object" ) );
1261                 }
1262                 break;
1263         case ID_CU:
1264                 if( self->object->type != OB_CURVE ) {
1265                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1266                                                         "The 'link' object is incompatible with the base object" ) );
1267                 }
1268                 break;
1269         case ID_LT:
1270                 if( self->object->type != OB_LATTICE ) {
1271                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1272                                                         "The 'link' object is incompatible with the base object" ) );
1273                 }
1274                 break;
1275         case ID_MB:
1276                 if( self->object->type != OB_MBALL ) {
1277                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1278                                                         "The 'link' object is incompatible with the base object" ) );
1279                 }
1280                 break;
1281         default:
1282                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1283                                                 "Linking this object type is not supported" ) );
1284         }
1285         self->object->data = data;
1286
1287         if( self->object->type == OB_MESH ) {
1288                 self->object->totcol = 0;
1289                 EXPP_synchronizeMaterialLists( self->object );
1290         }
1291
1292         id_us_plus( id );
1293         if( oldid ) {
1294                 if( oldid->us > 0 ) {
1295                         oldid->us--;
1296                 } else {
1297                         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1298                                                         "old object reference count below 0" ) );
1299                 }
1300         }
1301         return EXPP_incr_ret( Py_None );
1302 }
1303
1304 static PyObject *Object_makeParent( BPy_Object * self, PyObject * args )
1305 {
1306         PyObject *list;
1307         PyObject *py_child;
1308         //BPy_Object      * py_obj_child; unused
1309         Object *child;
1310         Object *parent;
1311         int noninverse = 0;
1312         int fast = 0;
1313         int i;
1314
1315         /* Check if the arguments passed to makeParent are valid. */
1316         if( !PyArg_ParseTuple( args, "O|ii", &list, &noninverse, &fast ) ) {
1317                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1318                                                 "expected a list of objects and one or two integers as arguments" ) );
1319         }
1320         if( !PySequence_Check( list ) ) {
1321                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1322                                                 "expected a list of objects" ) );
1323         }
1324
1325         /* Check if the PyObject passed in list is a Blender object. */
1326         for( i = 0; i < PySequence_Length( list ); i++ ) {
1327                 child = NULL;
1328                 py_child = PySequence_GetItem( list, i );
1329                 if( Object_CheckPyObject( py_child ) )
1330                         child = ( Object * ) Object_FromPyObject( py_child );
1331
1332                 if( child == NULL ) {
1333                         return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1334                                                         "Object Type expected" ) );
1335                 }
1336
1337                 parent = ( Object * ) self->object;
1338                 if( test_parent_loop( parent, child ) ) {
1339                         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1340                                                         "parenting loop detected - parenting failed" ) );
1341                 }
1342                 child->partype = PAROBJECT;
1343                 child->parent = parent;
1344                 //py_obj_child = (BPy_Object *) py_child;
1345                 if( noninverse == 1 ) {
1346                         /* Parent inverse = unity */
1347                         child->loc[0] = 0.0;
1348                         child->loc[1] = 0.0;
1349                         child->loc[2] = 0.0;
1350                 } else {
1351                         what_does_parent( child );
1352                         Mat4Invert( child->parentinv, parent->obmat );
1353                 }
1354
1355                 if( !fast ) {
1356                         sort_baselist( G.scene );
1357                 }
1358                 // We don't need the child object anymore.
1359                 //Py_DECREF ((PyObject *) child);
1360         }
1361         return EXPP_incr_ret( Py_None );
1362 }
1363
1364 static PyObject *Object_materialUsage( BPy_Object * self, PyObject * args )
1365 {
1366         return ( EXPP_ReturnPyObjError( PyExc_NotImplementedError,
1367                                         "materialUsage: not yet implemented" ) );
1368 }
1369
1370 static PyObject *Object_setDeltaLocation( BPy_Object * self, PyObject * args )
1371 {
1372         float dloc1;
1373         float dloc2;
1374         float dloc3;
1375         int status;
1376
1377         if( PyObject_Length( args ) == 3 )
1378                 status = PyArg_ParseTuple( args, "fff", &dloc1, &dloc2,
1379                                            &dloc3 );
1380         else
1381                 status = PyArg_ParseTuple( args, "(fff)", &dloc1, &dloc2,
1382                                            &dloc3 );
1383
1384         if( !status )
1385                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1386                                               "expected list argument of 3 floats" );
1387
1388         self->object->dloc[0] = dloc1;
1389         self->object->dloc[1] = dloc2;
1390         self->object->dloc[2] = dloc3;
1391
1392         Py_INCREF( Py_None );
1393         return ( Py_None );
1394 }
1395
1396 static PyObject *Object_setDrawMode( BPy_Object * self, PyObject * args )
1397 {
1398         char dtx;
1399
1400         if( !PyArg_ParseTuple( args, "b", &dtx ) ) {
1401                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1402                                                 "expected an integer as argument" ) );
1403         }
1404         self->object->dtx = dtx;
1405
1406         Py_INCREF( Py_None );
1407         return ( Py_None );
1408 }
1409
1410 static PyObject *Object_setDrawType( BPy_Object * self, PyObject * args )
1411 {
1412         char dt;
1413
1414         if( !PyArg_ParseTuple( args, "b", &dt ) ) {
1415                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1416                                                 "expected an integer as argument" ) );
1417         }
1418         self->object->dt = dt;
1419
1420         Py_INCREF( Py_None );
1421         return ( Py_None );
1422 }
1423
1424 static PyObject *Object_setEuler( BPy_Object * self, PyObject * args )
1425 {
1426         float rot1;
1427         float rot2;
1428         float rot3;
1429         int status = 0;         /* failure */
1430         PyObject *ob;
1431
1432         /* 
1433            args is either a tuple/list of floats or an euler.
1434            for backward compatibility, we also accept 3 floats.
1435          */
1436
1437         /* do we have 3 floats? */
1438         if( PyObject_Length( args ) == 3 ) {
1439                 status = PyArg_ParseTuple( args, "fff", &rot1, &rot2, &rot3 );
1440         } else {                //test to see if it's a list or a euler
1441                 if( PyArg_ParseTuple( args, "O", &ob ) ) {
1442                         if( EulerObject_Check( ob ) ) {
1443                                 rot1 = ( ( EulerObject * ) ob )->eul[0];
1444                                 rot2 = ( ( EulerObject * ) ob )->eul[1];
1445                                 rot3 = ( ( EulerObject * ) ob )->eul[2];
1446                                 status = 1;     /* success! */
1447                         } else if( PySequence_Check( ob ) )
1448                                 status = PyArg_ParseTuple( args, "(fff)",
1449                                                            &rot1, &rot2,
1450                                                            &rot3 );
1451                         else {  /* not an euler or tuple */
1452
1453                                 /* python C api doc says don't decref this */
1454                                 /*Py_DECREF (ob); */
1455
1456                                 status = 0;     /* false */
1457                         }
1458                 } else {        /* arg parsing failed */
1459                         status = 0;
1460                 }
1461         }
1462
1463         if( !status )           /* parsing args failed */
1464                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1465                                                 "expected euler or list/tuple of 3 floats " ) );
1466
1467         self->object->rot[0] = rot1;
1468         self->object->rot[1] = rot2;
1469         self->object->rot[2] = rot3;
1470
1471         Py_INCREF( Py_None );
1472         return ( Py_None );
1473 }
1474
1475
1476 static PyObject *Object_setMatrix( BPy_Object * self, PyObject * args )
1477 {
1478         MatrixObject *mat;
1479         int x, y;
1480
1481         if( !PyArg_ParseTuple( args, "O!", &matrix_Type, &mat ) )
1482                 return EXPP_ReturnPyObjError
1483                         ( PyExc_TypeError,
1484                           "expected matrix object as argument" );
1485
1486         for( x = 0; x < 4; x++ ) {
1487                 for( y = 0; y < 4; y++ ) {
1488                         self->object->obmat[x][y] = mat->matrix[x][y];
1489                 }
1490         }
1491         apply_obmat( self->object );
1492
1493         Py_INCREF( Py_None );
1494         return ( Py_None );
1495 }
1496
1497
1498 static PyObject *Object_setIpo( BPy_Object * self, PyObject * args )
1499 {
1500         PyObject *pyipo = 0;
1501         Ipo *ipo = NULL;
1502         Ipo *oldipo;
1503
1504         if( !PyArg_ParseTuple( args, "O!", &Ipo_Type, &pyipo ) )
1505                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1506                                               "expected Ipo as argument" );
1507
1508         ipo = Ipo_FromPyObject( pyipo );
1509
1510         if( !ipo )
1511                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1512                                               "null ipo!" );
1513
1514         if( ipo->blocktype != ID_OB )
1515                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1516                                               "this ipo is not an object ipo" );
1517
1518         oldipo = self->object->ipo;
1519         if( oldipo ) {
1520                 ID *id = &oldipo->id;
1521                 if( id->us > 0 )
1522                         id->us--;
1523         }
1524
1525         ( ( ID * ) & ipo->id )->us++;
1526
1527         self->object->ipo = ipo;
1528
1529         Py_INCREF( Py_None );
1530         return Py_None;
1531 }
1532
1533 static PyObject *Object_setLocation( BPy_Object * self, PyObject * args )
1534 {
1535         float loc1;
1536         float loc2;
1537         float loc3;
1538         int status;
1539
1540         if( PyObject_Length( args ) == 3 )
1541                 status = PyArg_ParseTuple( args, "fff", &loc1, &loc2, &loc3 );
1542         else
1543                 status = PyArg_ParseTuple( args, "(fff)", &loc1, &loc2,
1544                                            &loc3 );
1545
1546         if( !status )
1547                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1548                                               "expected list argument of 3 floats" );
1549
1550         self->object->loc[0] = loc1;
1551         self->object->loc[1] = loc2;
1552         self->object->loc[2] = loc3;
1553
1554         Py_INCREF( Py_None );
1555         return ( Py_None );
1556 }
1557
1558 static PyObject *Object_setMaterials( BPy_Object * self, PyObject * args )
1559 {
1560         PyObject *list;
1561         int len;
1562         int i;
1563         Material **matlist;
1564
1565         if( !PyArg_ParseTuple( args, "O", &list ) ) {
1566                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1567                                                 "expected a list of materials as argument" ) );
1568         }
1569
1570         len = PySequence_Length( list );
1571         if( len > 0 ) {
1572                 matlist = EXPP_newMaterialList_fromPyList( list );
1573                 if( !matlist ) {
1574                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1575                                                         "material list must be a list of valid materials!" ) );
1576                 }
1577                 if( ( len < 0 ) || ( len > MAXMAT ) ) {
1578                         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1579                                                         "material list should have at least 1, at most 16 entries" ) );
1580                 }
1581
1582                 if( self->object->mat ) {
1583                         EXPP_releaseMaterialList( self->object->mat,
1584                                                   self->object->totcol );
1585                 }
1586                 /* Increase the user count on all materials */
1587                 for( i = 0; i < len; i++ ) {
1588                         if( matlist[i] )
1589                                 id_us_plus( ( ID * ) matlist[i] );
1590                 }
1591                 self->object->mat = matlist;
1592                 self->object->totcol = len;
1593                 self->object->actcol = len;
1594
1595                 switch ( self->object->type ) {
1596                 case OB_CURVE:  /* fall through */
1597                 case OB_FONT:   /* fall through */
1598                 case OB_MESH:   /* fall through */
1599                 case OB_MBALL:  /* fall through */
1600                 case OB_SURF:
1601                         EXPP_synchronizeMaterialLists( self->object );
1602                         break;
1603                 default:
1604                         break;
1605                 }
1606         }
1607         return EXPP_incr_ret( Py_None );
1608 }
1609
1610 static PyObject *Object_setName( BPy_Object * self, PyObject * args )
1611 {
1612         char *name;
1613         char buf[21];
1614
1615         if( !PyArg_ParseTuple( args, "s", &name ) ) {
1616                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1617                                                 "expected a String as argument" ) );
1618         }
1619
1620         PyOS_snprintf( buf, sizeof( buf ), "%s", name );
1621
1622         rename_id( &self->object->id, buf );
1623
1624         Py_INCREF( Py_None );
1625         return ( Py_None );
1626 }
1627
1628 static PyObject *Object_setSize( BPy_Object * self, PyObject * args )
1629 {
1630         float sizex;
1631         float sizey;
1632         float sizez;
1633         int status;
1634
1635         if( PyObject_Length( args ) == 3 )
1636                 status = PyArg_ParseTuple( args, "fff", &sizex, &sizey,
1637                                            &sizez );
1638         else
1639                 status = PyArg_ParseTuple( args, "(fff)", &sizex, &sizey,
1640                                            &sizez );
1641
1642         if( !status )
1643                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1644                                               "expected list argument of 3 floats" );
1645
1646         self->object->size[0] = sizex;
1647         self->object->size[1] = sizey;
1648         self->object->size[2] = sizez;
1649
1650         Py_INCREF( Py_None );
1651         return ( Py_None );
1652 }
1653
1654 static PyObject *Object_setTimeOffset( BPy_Object * self, PyObject * args )
1655 {
1656         float newTimeOffset;
1657
1658         if( !PyArg_ParseTuple( args, "f", &newTimeOffset ) ) {
1659                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1660                                                 "expected a float as argument" ) );
1661         }
1662
1663         self->object->sf = newTimeOffset;
1664
1665         Py_INCREF( Py_None );
1666         return ( Py_None );
1667 }
1668
1669 static PyObject *Object_makeTrack( BPy_Object * self, PyObject * args )
1670 {
1671         BPy_Object *tracked = NULL;
1672         Object *ob = self->object;
1673         int fast = 0;
1674
1675         if( !PyArg_ParseTuple( args, "O!|i", &Object_Type, &tracked, &fast ) )
1676                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1677                                               "expected an object and optionally also an int as arguments." );
1678
1679         ob->track = tracked->object;
1680
1681         if( !fast )
1682                 sort_baselist( G.scene );
1683
1684         return EXPP_incr_ret( Py_None );
1685 }
1686
1687 static PyObject *Object_shareFrom( BPy_Object * self, PyObject * args )
1688 {
1689         BPy_Object *object;
1690         ID *id;
1691         ID *oldid;
1692
1693         if( !PyArg_ParseTuple( args, "O", &object ) ) {
1694                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1695                                               "expected an object argument" );
1696         }
1697         if( !Object_CheckPyObject( ( PyObject * ) object ) ) {
1698                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1699                                               "first argument is not of type 'Object'" );
1700         }
1701
1702         if( self->object->type != object->object->type ) {
1703                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1704                                               "objects are not of same data type" );
1705         }
1706         switch ( self->object->type ) {
1707         case OB_MESH:
1708         case OB_LAMP:
1709         case OB_CAMERA: /* we can probably add the other types, too */
1710         case OB_ARMATURE:
1711         case OB_CURVE:
1712         case OB_SURF:
1713         case OB_LATTICE:
1714                 oldid = ( ID * ) self->object->data;
1715                 id = ( ID * ) object->object->data;
1716                 self->object->data = object->object->data;
1717
1718                 if( self->object->type == OB_MESH && id ) {
1719                         self->object->totcol = 0;
1720                         EXPP_synchronizeMaterialLists( self->object );
1721                 }
1722
1723                 id_us_plus( id );
1724                 if( oldid ) {
1725                         if( oldid->us > 0 ) {
1726                                 oldid->us--;
1727                         } else {
1728                                 return ( EXPP_ReturnPyObjError
1729                                          ( PyExc_RuntimeError,
1730                                            "old object reference count below 0" ) );
1731                         }
1732                 }
1733                 Py_INCREF( Py_None );
1734                 return ( Py_None );
1735         default:
1736                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1737                                               "type not supported" );
1738         }
1739
1740         Py_INCREF( Py_None );
1741         return ( Py_None );
1742 }
1743
1744
1745
1746 static PyObject *Object_Select( BPy_Object * self, PyObject * args )
1747 {
1748         Base *base;
1749         int sel;
1750
1751         base = FIRSTBASE;
1752         if( !PyArg_ParseTuple( args, "i", &sel ) )
1753                 return EXPP_ReturnPyObjError
1754                         ( PyExc_TypeError, "expected an integer, 0 or 1" );
1755
1756         while( base ) {
1757                 if( base->object == self->object ) {
1758                         if( sel == 1 ) {
1759                                 base->flag |= SELECT;
1760                                 self->object->flag = base->flag;
1761                                 set_active_base( base );
1762                         } else {
1763                                 base->flag &= ~SELECT;
1764                                 self->object->flag = base->flag;
1765                         }
1766                         break;
1767                 }
1768                 base = base->next;
1769         }
1770
1771         countall(  );
1772
1773         Py_INCREF( Py_None );
1774         return ( Py_None );
1775 }
1776
1777 static PyObject *Object_getAllProperties( BPy_Object * self )
1778 {
1779         PyObject *prop_list;
1780         bProperty *prop = NULL;
1781
1782         prop_list = PyList_New( 0 );
1783
1784         prop = self->object->prop.first;
1785         while( prop ) {
1786                 PyList_Append( prop_list, Property_CreatePyObject( prop ) );
1787                 prop = prop->next;
1788         }
1789         return prop_list;
1790 }
1791
1792 static PyObject *Object_getProperty( BPy_Object * self, PyObject * args )
1793 {
1794         char *prop_name = NULL;
1795         bProperty *prop = NULL;
1796         PyObject *py_prop = Py_None;
1797
1798         if( !PyArg_ParseTuple( args, "s", &prop_name ) ) {
1799                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1800                                                 "expected a string" ) );
1801         }
1802
1803         prop = get_property( self->object, prop_name );
1804         if( prop ) {
1805                 py_prop = Property_CreatePyObject( prop );
1806         } else {
1807                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1808                                                 "couldn't find the property...." ) );
1809         }
1810         return py_prop;
1811 }
1812
1813 static PyObject *Object_addProperty( BPy_Object * self, PyObject * args )
1814 {
1815         bProperty *prop = NULL;
1816         char *prop_name = NULL;
1817         PyObject *prop_data = Py_None;
1818         char *prop_type = NULL;
1819         short type = -1;
1820         BPy_Property *py_prop = NULL;
1821         int argslen = PyObject_Length( args );
1822
1823         if( argslen == 3 || argslen == 2 ) {
1824                 if( !PyArg_ParseTuple
1825                     ( args, "sO|s", &prop_name, &prop_data, &prop_type ) ) {
1826                         return ( EXPP_ReturnPyObjError
1827                                  ( PyExc_AttributeError,
1828                                    "unable to get string, data, and optional string" ) );
1829                 }
1830         } else if( argslen == 1 ) {
1831                 if( !PyArg_ParseTuple( args, "O!", &property_Type, &py_prop ) ) {
1832                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1833                                                         "unable to get Property" ) );
1834                 }
1835                 if( py_prop->property != NULL ) {
1836                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1837                                                         "Property is already added to an object" ) );
1838                 }
1839         } else {
1840                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1841                                                 "expected 1,2 or 3 arguments" ) );
1842         }
1843
1844         //parse property type
1845         if( !py_prop ) {
1846                 if( prop_type ) {
1847                         if( BLI_streq( prop_type, "BOOL" ) )
1848                                 type = PROP_BOOL;
1849                         else if( BLI_streq( prop_type, "INT" ) )
1850                                 type = PROP_INT;
1851                         else if( BLI_streq( prop_type, "FLOAT" ) )
1852                                 type = PROP_FLOAT;
1853                         else if( BLI_streq( prop_type, "TIME" ) )
1854                                 type = PROP_TIME;
1855                         else if( BLI_streq( prop_type, "STRING" ) )
1856                                 type = PROP_STRING;
1857                         else
1858                                 return ( EXPP_ReturnPyObjError
1859                                          ( PyExc_RuntimeError,
1860                                            "BOOL, INT, FLOAT, TIME or STRING expected" ) );
1861                 } else {
1862                         //use the default
1863                         if( PyInt_Check( prop_data ) )
1864                                 type = PROP_INT;
1865                         else if( PyFloat_Check( prop_data ) )
1866                                 type = PROP_FLOAT;
1867                         else if( PyString_Check( prop_data ) )
1868                                 type = PROP_STRING;
1869                 }
1870         } else {
1871                 type = py_prop->type;
1872         }
1873
1874         //initialize a new bProperty of the specified type
1875         prop = new_property( type );
1876
1877         //parse data
1878         if( !py_prop ) {
1879                 BLI_strncpy( prop->name, prop_name, 32 );
1880                 if( PyInt_Check( prop_data ) ) {
1881                         *( ( int * ) &prop->data ) =
1882                                 ( int ) PyInt_AsLong( prop_data );
1883                 } else if( PyFloat_Check( prop_data ) ) {
1884                         *( ( float * ) &prop->data ) =
1885                                 ( float ) PyFloat_AsDouble( prop_data );
1886                 } else if( PyString_Check( prop_data ) ) {
1887                         BLI_strncpy( prop->poin,
1888                                      PyString_AsString( prop_data ),
1889                                      MAX_PROPSTRING );
1890                 }
1891         } else {
1892                 py_prop->property = prop;
1893                 if( !updateProperyData( py_prop ) ) {
1894                         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1895                                                         "Could not update property data - error" ) );
1896                 }
1897         }
1898
1899         //add to property listbase for the object
1900         BLI_addtail( &self->object->prop, prop );
1901
1902         return EXPP_incr_ret( Py_None );
1903 }
1904
1905 static PyObject *Object_removeProperty( BPy_Object * self, PyObject * args )
1906 {
1907         char *prop_name = NULL;
1908         BPy_Property *py_prop = NULL;
1909         bProperty *prop = NULL;
1910
1911         // we have property and no optional arg
1912         if( !PyArg_ParseTuple( args, "O!", &property_Type, &py_prop ) ) {
1913                 if( !PyArg_ParseTuple( args, "s", &prop_name ) ) {
1914                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1915                                                         "expected a Property or a string" ) );
1916                 }
1917         }
1918         //remove the link, free the data, and update the py struct
1919         if( py_prop ) {
1920                 BLI_remlink( &self->object->prop, py_prop->property );
1921                 if( updatePyProperty( py_prop ) ) {
1922                         free_property( py_prop->property );
1923                         py_prop->property = NULL;
1924                 }
1925         } else {
1926                 prop = get_property( self->object, prop_name );
1927                 if( prop ) {
1928                         BLI_remlink( &self->object->prop, prop );
1929                         free_property( prop );
1930                 }
1931         }
1932         return EXPP_incr_ret( Py_None );
1933 }
1934
1935 static PyObject *Object_removeAllProperties( BPy_Object * self )
1936 {
1937         free_properties( &self->object->prop );
1938         return EXPP_incr_ret( Py_None );
1939 }
1940
1941 static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
1942                                              PyObject * args )
1943 {
1944         PyObject *dest = Py_None;
1945         bProperty *prop = NULL;
1946         bProperty *propn = NULL;
1947
1948         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &dest ) ) {
1949                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1950                                                 "expected an Object" ) );
1951         }
1952         //make a copy of all it's properties
1953         prop = self->object->prop.first;
1954         while( prop ) {
1955                 propn = copy_property( prop );
1956                 BLI_addtail( &( ( BPy_Object * ) dest )->object->prop, propn );
1957                 prop = prop->next;
1958         }
1959
1960         return EXPP_incr_ret( Py_None );
1961 }
1962
1963 /* obj.addScriptLink */
1964 static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args )
1965 {
1966         Object *obj = self->object;
1967         ScriptLink *slink = NULL;
1968
1969         slink = &( obj )->scriptlink;
1970
1971         if( !EXPP_addScriptLink( slink, args, 0 ) )
1972                 return EXPP_incr_ret( Py_None );
1973         else
1974                 return NULL;
1975 }
1976
1977 /* obj.clearScriptLinks */
1978 static PyObject *Object_clearScriptLinks( BPy_Object * self )
1979 {
1980         Object *obj = self->object;
1981         ScriptLink *slink = NULL;
1982
1983         slink = &( obj )->scriptlink;
1984
1985         return EXPP_incr_ret( Py_BuildValue
1986                               ( "i", EXPP_clearScriptLinks( slink ) ) );
1987 }
1988
1989 /* obj.getScriptLinks */
1990 static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * args )
1991 {
1992         Object *obj = self->object;
1993         ScriptLink *slink = NULL;
1994         PyObject *ret = NULL;
1995
1996         slink = &( obj )->scriptlink;
1997
1998         ret = EXPP_getScriptLinks( slink, args, 0 );
1999
2000         if( ret )
2001                 return ret;
2002         else
2003                 return NULL;
2004 }
2005
2006 /*****************************************************************************/
2007 /* Function:    Object_CreatePyObject                                    */
2008 /* Description: This function will create a new BlenObject from an existing  */
2009 /*              Object structure.                                        */
2010 /*****************************************************************************/
2011 PyObject *Object_CreatePyObject( struct Object * obj )
2012 {
2013         BPy_Object *blen_object;
2014
2015         if( !obj )
2016                 return EXPP_incr_ret( Py_None );
2017
2018         blen_object =
2019                 ( BPy_Object * ) PyObject_NEW( BPy_Object, &Object_Type );
2020
2021         if( blen_object == NULL ) {
2022                 return ( NULL );
2023         }
2024         blen_object->object = obj;
2025         return ( ( PyObject * ) blen_object );
2026 }
2027
2028 /*****************************************************************************/
2029 /* Function:    Object_CheckPyObject                                     */
2030 /* Description: This function returns true when the given PyObject is of the */
2031 /*              type Object. Otherwise it will return false.             */
2032 /*****************************************************************************/
2033 int Object_CheckPyObject( PyObject * py_obj )
2034 {
2035         return ( py_obj->ob_type == &Object_Type );
2036 }
2037
2038 /*****************************************************************************/
2039 /* Function:    Object_FromPyObject                                      */
2040 /* Description: This function returns the Blender object from the given  */
2041 /*              PyObject.                                                */
2042 /*****************************************************************************/
2043 struct Object *Object_FromPyObject( PyObject * py_obj )
2044 {
2045         BPy_Object *blen_obj;
2046
2047         blen_obj = ( BPy_Object * ) py_obj;
2048         return ( blen_obj->object );
2049 }
2050
2051 /*****************************************************************************/
2052 /* Description: Returns the object with the name specified by the argument  */
2053 /*              name. Note that the calling function has to remove the first */
2054 /*              two characters of the object name. These two characters    */
2055 /*              specify the type of the object (OB, ME, WO, ...)         */
2056 /*              The function will return NULL when no object with the given  */
2057 /*              name is found.                                           */
2058 /*****************************************************************************/
2059 Object *GetObjectByName( char *name )
2060 {
2061         Object *obj_iter;
2062
2063         obj_iter = G.main->object.first;
2064         while( obj_iter ) {
2065                 if( StringEqual( name, GetIdName( &( obj_iter->id ) ) ) ) {
2066                         return ( obj_iter );
2067                 }
2068                 obj_iter = obj_iter->id.next;
2069         }
2070
2071         /* There is no object with the given name */
2072         return ( NULL );
2073 }
2074
2075 /*****************************************************************************/
2076 /* Function:    Object_dealloc                                           */
2077 /* Description: This is a callback function for the BlenObject type. It is  */
2078 /*              the destructor function.                                 */
2079 /*****************************************************************************/
2080 static void Object_dealloc( BPy_Object * obj )
2081 {
2082         PyObject_DEL( obj );
2083 }
2084
2085 /*****************************************************************************/
2086 /* Function:    Object_getAttr                                           */
2087 /* Description: This is a callback function for the BlenObject type. It is  */
2088 /*              the function that retrieves any value from Blender and   */
2089 /*              passes it to Python.                                     */
2090 /*****************************************************************************/
2091 static PyObject *Object_getAttr( BPy_Object * obj, char *name )
2092 {
2093         struct Object *object;
2094         struct Ika *ika;
2095
2096         object = obj->object;
2097         if( StringEqual( name, "LocX" ) )
2098                 return ( PyFloat_FromDouble( object->loc[0] ) );
2099         if( StringEqual( name, "LocY" ) )
2100                 return ( PyFloat_FromDouble( object->loc[1] ) );
2101         if( StringEqual( name, "LocZ" ) )
2102                 return ( PyFloat_FromDouble( object->loc[2] ) );
2103         if( StringEqual( name, "loc" ) )
2104                 return ( Py_BuildValue( "fff", object->loc[0], object->loc[1],
2105                                         object->loc[2] ) );
2106         if( StringEqual( name, "dLocX" ) )
2107                 return ( PyFloat_FromDouble( object->dloc[0] ) );
2108         if( StringEqual( name, "dLocY" ) )
2109                 return ( PyFloat_FromDouble( object->dloc[1] ) );
2110         if( StringEqual( name, "dLocZ" ) )
2111                 return ( PyFloat_FromDouble( object->dloc[2] ) );
2112         if( StringEqual( name, "dloc" ) )
2113                 return ( Py_BuildValue
2114                          ( "fff", object->dloc[0], object->dloc[1],
2115                            object->dloc[2] ) );
2116         if( StringEqual( name, "RotX" ) )
2117                 return ( PyFloat_FromDouble( object->rot[0] ) );
2118         if( StringEqual( name, "RotY" ) )
2119                 return ( PyFloat_FromDouble( object->rot[1] ) );
2120         if( StringEqual( name, "RotZ" ) )
2121                 return ( PyFloat_FromDouble( object->rot[2] ) );
2122         if( StringEqual( name, "rot" ) )
2123                 return ( Py_BuildValue( "fff", object->rot[0], object->rot[1],
2124                                         object->rot[2] ) );
2125         if( StringEqual( name, "dRotX" ) )
2126                 return ( PyFloat_FromDouble( object->drot[0] ) );
2127         if( StringEqual( name, "dRotY" ) )
2128                 return ( PyFloat_FromDouble( object->drot[1] ) );
2129         if( StringEqual( name, "dRotZ" ) )
2130                 return ( PyFloat_FromDouble( object->drot[2] ) );
2131         if( StringEqual( name, "drot" ) )
2132                 return ( Py_BuildValue
2133                          ( "fff", object->drot[0], object->drot[1],
2134                            object->drot[2] ) );
2135         if( StringEqual( name, "SizeX" ) )
2136                 return ( PyFloat_FromDouble( object->size[0] ) );
2137         if( StringEqual( name, "SizeY" ) )
2138                 return ( PyFloat_FromDouble( object->size[1] ) );
2139         if( StringEqual( name, "SizeZ" ) )
2140                 return ( PyFloat_FromDouble( object->size[2] ) );
2141         if( StringEqual( name, "size" ) )
2142                 return ( Py_BuildValue
2143                          ( "fff", object->size[0], object->size[1],
2144                            object->size[2] ) );
2145         if( StringEqual( name, "dSizeX" ) )
2146                 return ( PyFloat_FromDouble( object->dsize[0] ) );
2147         if( StringEqual( name, "dSizeY" ) )
2148                 return ( PyFloat_FromDouble( object->dsize[1] ) );
2149         if( StringEqual( name, "dSizeZ" ) )
2150                 return ( PyFloat_FromDouble( object->dsize[2] ) );
2151         if( StringEqual( name, "dsize" ) )
2152                 return ( Py_BuildValue
2153                          ( "fff", object->dsize[0], object->dsize[1],
2154                            object->dsize[2] ) );
2155         if( strncmp( name, "Eff", 3 ) == 0 ) {
2156                 if( ( object->type == OB_IKA ) && ( object->data != NULL ) ) {
2157                         ika = object->data;
2158                         switch ( name[3] ) {
2159                         case 'X':
2160                                 return ( PyFloat_FromDouble( ika->effg[0] ) );
2161                         case 'Y':
2162                                 return ( PyFloat_FromDouble( ika->effg[1] ) );
2163                         case 'Z':
2164                                 return ( PyFloat_FromDouble( ika->effg[2] ) );
2165                         default:
2166                                 /* Do we need to display a sensible error message here? */
2167                                 return ( NULL );
2168                         }
2169                 }
2170                 return ( NULL );
2171         }
2172         if( StringEqual( name, "Layer" ) )
2173                 return ( PyInt_FromLong( object->lay ) );
2174         if( StringEqual( name, "parent" ) ) {
2175                 if( object->parent )
2176                         return ( Object_CreatePyObject( object->parent ) );
2177                 else {
2178                         Py_INCREF( Py_None );
2179                         return ( Py_None );
2180                 }
2181         }
2182
2183         if( StringEqual( name, "track" ) )
2184                 return ( Object_CreatePyObject( object->track ) );
2185         if( StringEqual( name, "data" ) ) {
2186                 PyObject *getdata, *tuple = PyTuple_New(0);
2187
2188                 if (!tuple)
2189                         return EXPP_ReturnPyObjError (PyExc_MemoryError,
2190                                 "couldn't create an empty tuple!");
2191
2192                 getdata = Object_getData( obj, tuple, NULL );
2193
2194                 Py_DECREF(tuple);
2195                 return getdata;
2196         }
2197         if( StringEqual( name, "ipo" ) ) {
2198                 if( object->ipo == NULL ) {
2199                         /* There's no ipo linked to the object, return Py_None. */
2200                         Py_INCREF( Py_None );
2201                         return ( Py_None );
2202                 }
2203                 return ( Ipo_CreatePyObject( object->ipo ) );
2204         }
2205         if( StringEqual( name, "mat" ) || StringEqual( name, "matrix" ) )
2206                 return ( Object_getMatrix
2207                          ( obj, Py_BuildValue( "(s)", "worldspace" ) ) );
2208         if( StringEqual( name, "matrixWorld" ) )
2209                 return ( Object_getMatrix
2210                          ( obj, Py_BuildValue( "(s)", "worldspace" ) ) );
2211         if( StringEqual( name, "matrixLocal" ) )
2212                 return ( Object_getMatrix
2213                          ( obj, Py_BuildValue( "(s)", "localspace" ) ) );
2214         if( StringEqual( name, "colbits" ) )
2215                 return ( Py_BuildValue( "h", object->colbits ) );
2216         if( StringEqual( name, "drawType" ) )
2217                 return ( Py_BuildValue( "b", object->dt ) );
2218         if( StringEqual( name, "drawMode" ) )
2219                 return ( Py_BuildValue( "b", object->dtx ) );
2220         if( StringEqual( name, "name" ) )
2221                 return ( Py_BuildValue( "s", object->id.name + 2 ) );
2222         if( StringEqual( name, "sel" ) )
2223                 return ( Object_isSelected( obj ) );
2224         if (StringEqual (name, "oopsLoc")) {
2225                 if (G.soops) {
2226       Oops *oops= G.soops->oops.first;
2227       while(oops) {
2228         if(oops->type==ID_OB) {
2229           if ((Object *)oops->id == object) {
2230             return (Py_BuildValue ("ff", oops->x, oops->y));
2231           }
2232         }
2233         oops= oops->next;
2234       }
2235     }
2236                 return EXPP_incr_ret( Py_None );
2237         }
2238
2239         /* not an attribute, search the methods table */
2240         return Py_FindMethod( BPy_Object_methods, ( PyObject * ) obj, name );
2241 }
2242
2243 /*****************************************************************************/
2244 /* Function:    Object_setAttr                                           */
2245 /* Description: This is a callback function for the BlenObject type. It is  */
2246 /*              the function that retrieves any value from Python and sets  */
2247 /*              it accordingly in Blender.                               */
2248 /*****************************************************************************/
2249 static int Object_setAttr( BPy_Object * obj, char *name, PyObject * value )
2250 {
2251         PyObject *valtuple;
2252         struct Object *object;
2253         struct Ika *ika;
2254
2255         /* First put the value(s) in a tuple. For some variables, we want to */
2256         /* pass the values to a function, and these functions only accept */
2257         /* PyTuples. */
2258         valtuple = Py_BuildValue( "(O)", value );
2259         if( !valtuple ) {
2260                 return EXPP_ReturnIntError( PyExc_MemoryError,
2261                                             "Object_setAttr: couldn't create PyTuple" );
2262         }
2263
2264         object = obj->object;
2265         if( StringEqual( name, "LocX" ) )
2266                 return ( !PyArg_Parse( value, "f", &( object->loc[0] ) ) );
2267         if( StringEqual( name, "LocY" ) )
2268                 return ( !PyArg_Parse( value, "f", &( object->loc[1] ) ) );
2269         if( StringEqual( name, "LocZ" ) )
2270                 return ( !PyArg_Parse( value, "f", &( object->loc[2] ) ) );
2271         if( StringEqual( name, "loc" ) ) {
2272                 if( Object_setLocation( obj, valtuple ) != Py_None )
2273                         return ( -1 );
2274                 else
2275                         return ( 0 );
2276         }
2277         if( StringEqual( name, "dLocX" ) )
2278                 return ( !PyArg_Parse( value, "f", &( object->dloc[0] ) ) );
2279         if( StringEqual( name, "dLocY" ) )
2280                 return ( !PyArg_Parse( value, "f", &( object->dloc[1] ) ) );
2281         if( StringEqual( name, "dLocZ" ) )
2282                 return ( !PyArg_Parse( value, "f", &( object->dloc[2] ) ) );
2283         if( StringEqual( name, "dloc" ) ) {
2284                 if( Object_setDeltaLocation( obj, valtuple ) != Py_None )
2285                         return ( -1 );
2286                 else
2287                         return ( 0 );
2288         }
2289         if( StringEqual( name, "RotX" ) )
2290                 return ( !PyArg_Parse( value, "f", &( object->rot[0] ) ) );
2291         if( StringEqual( name, "RotY" ) )
2292                 return ( !PyArg_Parse( value, "f", &( object->rot[1] ) ) );
2293         if( StringEqual( name, "RotZ" ) )
2294                 return ( !PyArg_Parse( value, "f", &( object->rot[2] ) ) );
2295         if( StringEqual( name, "rot" ) ) {
2296                 if( Object_setEuler( obj, valtuple ) != Py_None )
2297                         return ( -1 );
2298                 else
2299                         return ( 0 );
2300         }
2301         if( StringEqual( name, "dRotX" ) )
2302                 return ( !PyArg_Parse( value, "f", &( object->drot[0] ) ) );
2303         if( StringEqual( name, "dRotY" ) )
2304                 return ( !PyArg_Parse( value, "f", &( object->drot[1] ) ) );
2305         if( StringEqual( name, "dRotZ" ) )
2306                 return ( !PyArg_Parse( value, "f", &( object->drot[2] ) ) );
2307         if( StringEqual( name, "drot" ) )
2308                 return ( !PyArg_ParseTuple( value, "fff", &( object->drot[0] ),
2309                                             &( object->drot[1] ),
2310                                             &( object->drot[2] ) ) );
2311         if( StringEqual( name, "SizeX" ) )
2312                 return ( !PyArg_Parse( value, "f", &( object->size[0] ) ) );
2313         if( StringEqual( name, "SizeY" ) )
2314                 return ( !PyArg_Parse( value, "f", &( object->size[1] ) ) );
2315         if( StringEqual( name, "SizeZ" ) )
2316                 return ( !PyArg_Parse( value, "f", &( object->size[2] ) ) );
2317         if( StringEqual( name, "size" ) )
2318                 return ( !PyArg_ParseTuple( value, "fff", &( object->size[0] ),
2319                                             &( object->size[1] ),
2320                                             &( object->size[2] ) ) );
2321         if( StringEqual( name, "dSizeX" ) )
2322                 return ( !PyArg_Parse( value, "f", &( object->dsize[0] ) ) );
2323         if( StringEqual( name, "dSizeY" ) )
2324                 return ( !PyArg_Parse( value, "f", &( object->dsize[1] ) ) );
2325         if( StringEqual( name, "dSizeZ" ) )
2326                 return ( !PyArg_Parse( value, "f", &( object->dsize[2] ) ) );
2327         if( StringEqual( name, "dsize" ) )
2328                 return ( !PyArg_ParseTuple
2329                          ( value, "fff", &( object->dsize[0] ),
2330                            &( object->dsize[1] ), &( object->dsize[2] ) ) );
2331         if( strncmp( name, "Eff", 3 ) == 0 ) {
2332                 if( ( object->type == OB_IKA ) && ( object->data != NULL ) ) {
2333                         ika = object->data;
2334                         switch ( name[3] ) {
2335                         case 'X':
2336                                 return ( !PyArg_Parse
2337                                          ( value, "f", &( ika->effg[0] ) ) );
2338                         case 'Y':
2339                                 return ( !PyArg_Parse
2340                                          ( value, "f", &( ika->effg[1] ) ) );
2341                         case 'Z':
2342                                 return ( !PyArg_Parse
2343                                          ( value, "f", &( ika->effg[2] ) ) );
2344                         default:
2345                                 /* Do we need to display a sensible error message here? */
2346                                 return ( 0 );
2347                         }
2348                 }
2349                 return ( 0 );
2350         }
2351         if( StringEqual( name, "Layer" ) ) {
2352                 /*  usage note: caller of this func needs to do a 
2353                    Blender.Redraw(-1) to update and redraw the interface */
2354
2355                 Base *base;
2356                 int newLayer;
2357                 int local;
2358
2359                 if( ! PyArg_Parse( value, "i", &newLayer ) ) {
2360                         return EXPP_ReturnIntError( PyExc_AttributeError,
2361                                                     "expected int as bitmask" );
2362                 }
2363
2364                 /* uppper 2 nibbles are for local view */
2365                 newLayer &= 0x00FFFFFF;
2366                 if( newLayer == 0 )     /* bail if nothing to do */
2367                         return ( 0 );
2368                 
2369                 /* update any bases pointing to our object */
2370                 base = FIRSTBASE;  /* first base in current scene */
2371                 while( base ){
2372                         if( base->object == obj->object ) {
2373                                 local = base->lay &= 0xFF000000;
2374                                 base->lay = local | newLayer;
2375                                 object->lay = base->lay;
2376                         }
2377                         base = base->next;
2378                 }
2379                 countall(  );
2380                 
2381                 return ( 0 );
2382         }
2383         if( StringEqual( name, "parent" ) ) {
2384                 /* This is not allowed. */
2385                 EXPP_ReturnPyObjError( PyExc_AttributeError,
2386                                        "Setting the parent is not allowed." );
2387                 return ( 0 );
2388         }
2389         if( StringEqual( name, "track" ) ) {
2390                 if( Object_makeTrack( obj, valtuple ) != Py_None )
2391                         return ( -1 );
2392                 else
2393                         return ( 0 );
2394         }
2395         if( StringEqual( name, "data" ) ) {
2396                 /* This is not allowed. */
2397                 EXPP_ReturnPyObjError( PyExc_AttributeError,
2398                                        "Setting the data is not allowed." );
2399                 return ( 0 );
2400         }
2401         if( StringEqual( name, "ipo" ) ) {
2402                 /* This is not allowed. */
2403                 EXPP_ReturnPyObjError( PyExc_AttributeError,
2404                                        "Setting the ipo is not allowed." );
2405                 return ( 0 );
2406         }
2407         if( StringEqual( name, "mat" ) ) {
2408                 /* This is not allowed. */
2409                 EXPP_ReturnPyObjError( PyExc_AttributeError,
2410                                        "Setting the matrix is not allowed." );
2411                 return ( 0 );
2412         }
2413         if( StringEqual( name, "matrix" ) ) {
2414                 /* This is not allowed. */
2415                 EXPP_ReturnPyObjError( PyExc_AttributeError,
2416                                        "Please use .setMatrix(matrix)" );
2417                 return ( 0 );
2418         }
2419         if( StringEqual( name, "colbits" ) )
2420                 return ( !PyArg_Parse( value, "h", &( object->colbits ) ) );
2421         if( StringEqual( name, "drawType" ) ) {
2422                 if( Object_setDrawType( obj, valtuple ) != Py_None )
2423                         return ( -1 );
2424                 else
2425                         return ( 0 );
2426         }
2427         if( StringEqual( name, "drawMode" ) ) {
2428                 if( Object_setDrawMode( obj, valtuple ) != Py_None )
2429                         return ( -1 );
2430                 else
2431                         return ( 0 );
2432         }
2433         if( StringEqual( name, "name" ) ) {
2434                 if( Object_setName( obj, valtuple ) != Py_None )
2435                         return ( -1 );
2436                 else
2437                         return ( 0 );
2438         }
2439         if( StringEqual( name, "sel" ) ) {
2440                 if( Object_Select( obj, valtuple ) != Py_None )
2441                         return ( -1 );
2442                 else
2443                         return ( 0 );
2444         }
2445         if (StringEqual (name, "oopsLoc")) {
2446                 if (G.soops) {
2447                         Oops *oops= G.soops->oops.first;
2448                         while(oops) {
2449                                 if(oops->type==ID_OB) {
2450                                         if ((Object *)oops->id == object) {
2451                                                 return (!PyArg_ParseTuple  (value, "ff", &(oops->x),&(oops->y)));
2452                                         }
2453                                 }
2454                                 oops= oops->next;
2455                         }
2456                 }
2457                 return 0;
2458         }
2459
2460         return EXPP_ReturnIntError( PyExc_KeyError, "attribute not found" );
2461 }
2462
2463 /*****************************************************************************/
2464 /* Function:    Object_compare                                           */
2465 /* Description: This is a callback function for the BPy_Object type. It  */
2466 /*              compares two Object_Type objects. Only the "==" and "!="  */
2467 /*              comparisons are meaninful. Returns 0 for equality and -1 if  */
2468 /*              they don't point to the same Blender Object struct.      */
2469 /*              In Python it becomes 1 if they are equal, 0 otherwise.   */
2470 /*****************************************************************************/
2471 static int Object_compare( BPy_Object * a, BPy_Object * b )
2472 {
2473         Object *pa = a->object, *pb = b->object;
2474         return ( pa == pb ) ? 0 : -1;
2475 }
2476
2477 /*****************************************************************************/
2478 /* Function:    Object_repr                                              */
2479 /* Description: This is a callback function for the BPy_Object type. It  */
2480 /*              builds a meaninful string to represent object objects.   */
2481 /*****************************************************************************/
2482 static PyObject *Object_repr( BPy_Object * self )
2483 {
2484         return PyString_FromFormat( "[Object \"%s\"]",
2485                                     self->object->id.name + 2 );
2486 }