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