Reason of all this work: Commiting my work-in-progress on reviewed collision system...
[blender.git] / source / blender / python / api2_2x / Object.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  *
24  * The Object module provides generic access to Objects of various types via
25  * the Python interface.
26  *
27  *
28  * Contributor(s): Michel Selten, Willian Germano, Jacques Guignot,
29  * Joseph Gilbert, Stephen Swaney, Bala Gi, Campbell Barton, Johnny Matthews,
30  * Ken Hughes, Alex Mole, Jean-Michel Soler
31  *
32  * ***** END GPL LICENSE BLOCK *****
33 */
34
35 struct SpaceIpo;
36 struct rctf;
37
38 #include "Object.h" /*This must come first */
39
40 #include "DNA_object_types.h"
41 #include "DNA_view3d_types.h"
42 #include "DNA_object_force.h"
43 #include "DNA_userdef_types.h"
44 #include "DNA_key_types.h" /* for pinShape and activeShape */
45
46 #include "BKE_action.h"
47 #include "BKE_anim.h" /* used for dupli-objects */
48 #include "BKE_depsgraph.h"
49 #include "BKE_effect.h"
50 #include "BKE_font.h"
51 #include "BKE_property.h"
52 #include "BKE_mball.h"
53 #include "BKE_softbody.h"
54 #include "BKE_utildefines.h"
55 #include "BKE_armature.h"
56 #include "BKE_lattice.h"
57 #include "BKE_mesh.h"
58 #include "BKE_library.h"
59 #include "BKE_object.h"
60 #include "BKE_curve.h"
61 #include "BKE_global.h"
62 #include "BKE_main.h"
63 #include "BKE_scene.h"
64 #include "BKE_nla.h"
65 #include "BKE_material.h"
66 #include "BKE_modifier.h"
67 #include "BKE_idprop.h"
68 #include "BKE_object.h"
69 #include "BKE_key.h" /* for setting the activeShape */
70 #include "BKE_displist.h"
71
72 #include "BSE_editipo.h"
73 #include "BSE_edit.h"
74
75 #include "BIF_space.h"
76 #include "BIF_editview.h"
77 #include "BIF_drawscene.h"
78 #include "BIF_meshtools.h"
79 #include "BIF_editarmature.h"
80 #include "BIF_editaction.h"
81 #include "BIF_editnla.h"
82
83 #include "BLI_arithb.h"
84 #include "BLI_blenlib.h"
85
86 #include "BDR_editobject.h"
87 #include "BDR_editcurve.h"
88 #include "BDR_drawobject.h"
89
90 #include "MEM_guardedalloc.h"
91
92 #include "mydevice.h"
93 #include "blendef.h"
94 #include "Scene.h"
95 #include "Mathutils.h"
96 #include "Mesh.h"
97 #include "NMesh.h"
98 #include "Curve.h"
99 #include "Ipo.h"
100 #include "Armature.h"
101 #include "Pose.h"
102 #include "Camera.h"
103 #include "Lamp.h"
104 #include "Lattice.h"
105 #include "Text.h"
106 #include "Text3d.h"
107 #include "Metaball.h"
108 #include "Draw.h"
109 #include "NLA.h"
110 #include "logic.h"
111 #include "Effect.h"
112 #include "Group.h"
113 #include "Modifier.h"
114 #include "Constraint.h"
115 #include "gen_utils.h"
116 #include "gen_library.h"
117 #include "EXPP_interface.h"
118 #include "BIF_editkey.h"
119 #include "IDProp.h"
120
121 /* Defines for insertIpoKey */
122
123 #define IPOKEY_LOC              0
124 #define IPOKEY_ROT              1
125 #define IPOKEY_SIZE             2
126 #define IPOKEY_LOCROT           3
127 #define IPOKEY_LOCROTSIZE       4
128 #define IPOKEY_PI_STRENGTH      5
129 #define IPOKEY_PI_FALLOFF       6
130 #define IPOKEY_PI_MAXDIST       7 /*Not Ready Yet*/
131 #define IPOKEY_PI_SURFACEDAMP   8
132 #define IPOKEY_PI_RANDOMDAMP    9
133 #define IPOKEY_PI_PERM          10
134 #define IPOKEY_LAYER                    19
135
136 #define PFIELD_FORCE    1
137 #define PFIELD_VORTEX   2
138 #define PFIELD_MAGNET   3
139 #define PFIELD_WIND             4
140
141 enum obj_consts {
142         EXPP_OBJ_ATTR_LOC_X = 0,
143         EXPP_OBJ_ATTR_LOC_Y,
144         EXPP_OBJ_ATTR_LOC_Z,
145         EXPP_OBJ_ATTR_DLOC_X,
146         EXPP_OBJ_ATTR_DLOC_Y,
147         EXPP_OBJ_ATTR_DLOC_Z,
148         EXPP_OBJ_ATTR_ROT_X,
149         EXPP_OBJ_ATTR_ROT_Y,
150         EXPP_OBJ_ATTR_ROT_Z,
151         EXPP_OBJ_ATTR_DROT_X,
152         EXPP_OBJ_ATTR_DROT_Y,
153         EXPP_OBJ_ATTR_DROT_Z,
154         EXPP_OBJ_ATTR_SIZE_X,
155         EXPP_OBJ_ATTR_SIZE_Y,
156         EXPP_OBJ_ATTR_SIZE_Z,
157         EXPP_OBJ_ATTR_DSIZE_X,
158         EXPP_OBJ_ATTR_DSIZE_Y,
159         EXPP_OBJ_ATTR_DSIZE_Z,
160         EXPP_OBJ_ATTR_LOC,
161         EXPP_OBJ_ATTR_DLOC,
162         EXPP_OBJ_ATTR_DROT,
163         EXPP_OBJ_ATTR_SIZE,
164         EXPP_OBJ_ATTR_DSIZE,
165         EXPP_OBJ_ATTR_LAYERMASK,
166         EXPP_OBJ_ATTR_COLBITS,
167         EXPP_OBJ_ATTR_DRAWMODE,
168         EXPP_OBJ_ATTR_DRAWTYPE,
169         EXPP_OBJ_ATTR_DUPON,
170         EXPP_OBJ_ATTR_DUPOFF,
171         EXPP_OBJ_ATTR_DUPSTA,
172         EXPP_OBJ_ATTR_DUPEND,
173         EXPP_OBJ_ATTR_DUPFACESCALEFAC,
174         EXPP_OBJ_ATTR_TIMEOFFSET,
175         EXPP_OBJ_ATTR_DRAWSIZE,
176         EXPP_OBJ_ATTR_PARENT_TYPE,
177         EXPP_OBJ_ATTR_PASSINDEX,
178         EXPP_OBJ_ATTR_ACT_MATERIAL,
179         EXPP_OBJ_ATTR_ACT_SHAPE,
180         
181         EXPP_OBJ_ATTR_PI_SURFACEDAMP,   /* these need to stay together */
182         EXPP_OBJ_ATTR_PI_RANDOMDAMP,    /* and in order */
183         EXPP_OBJ_ATTR_PI_PERM,
184         EXPP_OBJ_ATTR_PI_STRENGTH,
185         EXPP_OBJ_ATTR_PI_FALLOFF,
186         EXPP_OBJ_ATTR_PI_MAXDIST,
187         EXPP_OBJ_ATTR_PI_SBDAMP,
188         EXPP_OBJ_ATTR_PI_SBIFACETHICK,
189         EXPP_OBJ_ATTR_PI_SBOFACETHICK,
190
191         EXPP_OBJ_ATTR_SB_NODEMASS,      /* these need to stay together */
192         EXPP_OBJ_ATTR_SB_GRAV,          /* and in order */
193         EXPP_OBJ_ATTR_SB_MEDIAFRICT,
194         EXPP_OBJ_ATTR_SB_RKLIMIT,
195         EXPP_OBJ_ATTR_SB_PHYSICSSPEED,
196         EXPP_OBJ_ATTR_SB_GOALSPRING,
197         EXPP_OBJ_ATTR_SB_GOALFRICT,
198         EXPP_OBJ_ATTR_SB_MINGOAL,
199         EXPP_OBJ_ATTR_SB_MAXGOAL,
200         EXPP_OBJ_ATTR_SB_DEFGOAL,
201         EXPP_OBJ_ATTR_SB_INSPRING,
202         EXPP_OBJ_ATTR_SB_INFRICT,
203
204 };
205
206 #define EXPP_OBJECT_DRAWSIZEMIN         0.01f
207 #define EXPP_OBJECT_DRAWSIZEMAX         10.0f
208
209 /* clamping and range values for particle interaction settings */
210 #define EXPP_OBJECT_PIDAMP_MIN           0.0f
211 #define EXPP_OBJECT_PIDAMP_MAX           1.0f
212 #define EXPP_OBJECT_PIRDAMP_MIN          0.0f
213 #define EXPP_OBJECT_PIRDAMP_MAX          1.0f
214 #define EXPP_OBJECT_PIPERM_MIN           0.0f
215 #define EXPP_OBJECT_PIPERM_MAX           1.0f
216 #define EXPP_OBJECT_PISTRENGTH_MIN       0.0f
217 #define EXPP_OBJECT_PISTRENGTH_MAX    1000.0f
218 #define EXPP_OBJECT_PIPOWER_MIN          0.0f
219 #define EXPP_OBJECT_PIPOWER_MAX         10.0f
220 #define EXPP_OBJECT_PIMAXDIST_MIN        0.0f
221 #define EXPP_OBJECT_PIMAXDIST_MAX     1000.0f
222 #define EXPP_OBJECT_PISBDAMP_MIN         0.0f
223 #define EXPP_OBJECT_PISBDAMP_MAX         1.0f
224 #define EXPP_OBJECT_PISBIFTMIN         0.001f
225 #define EXPP_OBJECT_PISBIFTMAX           1.0f
226 #define EXPP_OBJECT_PISBOFTMIN         0.001f
227 #define EXPP_OBJECT_PISBOFTMAX           1.0f
228
229 /* clamping and range values for softbody settings */
230 #define EXPP_OBJECT_SBMASS_MIN           0.0f
231 #define EXPP_OBJECT_SBMASS_MAX          50.0f
232 #define EXPP_OBJECT_SBGRAVITY_MIN        0.0f
233 #define EXPP_OBJECT_SBGRAVITY_MAX       10.0f
234 #define EXPP_OBJECT_SBFRICTION_MIN       0.0f
235 #define EXPP_OBJECT_SBFRICTION_MAX      10.0f
236 #define EXPP_OBJECT_SBSPEED_MIN          0.01f
237 #define EXPP_OBJECT_SBSPEED_MAX        100.0f
238 #define EXPP_OBJECT_SBERRORLIMIT_MIN     0.01f
239 #define EXPP_OBJECT_SBERRORLIMIT_MAX     1.0f
240 #define EXPP_OBJECT_SBGOALSPRING_MIN     0.0f
241 #define EXPP_OBJECT_SBGOALSPRING_MAX     0.999f
242 #define EXPP_OBJECT_SBGOALFRICT_MIN      0.0f
243 #define EXPP_OBJECT_SBGOALFRICT_MAX     10.0f
244 #define EXPP_OBJECT_SBMINGOAL_MIN        0.0f
245 #define EXPP_OBJECT_SBMINGOAL_MAX        1.0f
246 #define EXPP_OBJECT_SBMAXGOAL_MIN        0.0f
247 #define EXPP_OBJECT_SBMAXGOAL_MAX        1.0f
248 #define EXPP_OBJECT_SBINSPRING_MIN       0.0f
249 #define EXPP_OBJECT_SBINSPRING_MAX     0.999f
250 #define EXPP_OBJECT_SBINFRICT_MIN        0.0f
251 #define EXPP_OBJECT_SBINFRICT_MAX       10.0f
252 #define EXPP_OBJECT_SBDEFGOAL_MIN        0.0f
253 #define EXPP_OBJECT_SBDEFGOAL_MAX        1.0f
254 #define EXPP_OBJECT_SBNODEMASSMIN      0.001f
255 #define EXPP_OBJECT_SBNODEMASSMAX       50.0f
256 #define EXPP_OBJECT_SBGRAVMIN            0.0f
257 #define EXPP_OBJECT_SBGRAVMAX           10.0f
258 #define EXPP_OBJECT_SBMEDIAFRICTMIN      0.0f
259 #define EXPP_OBJECT_SBMEDIAFRICTMAX     10.0f
260 #define EXPP_OBJECT_SBRKLIMITMIN        0.01f
261 #define EXPP_OBJECT_SBRKLIMITMAX         1.0f
262 #define EXPP_OBJECT_SBPHYSICSSPEEDMIN   0.01f
263 #define EXPP_OBJECT_SBPHYSICSSPEEDMAX  100.0f
264 #define EXPP_OBJECT_SBGOALSPRINGMIN      0.0f
265 #define EXPP_OBJECT_SBGOALSPRINGMAX    0.999f
266 #define EXPP_OBJECT_SBGOALFRICTMIN       0.0f
267 #define EXPP_OBJECT_SBGOALFRICTMAX      10.0f
268 #define EXPP_OBJECT_SBMINGOALMIN         0.0f
269 #define EXPP_OBJECT_SBMINGOALMAX         1.0f
270 #define EXPP_OBJECT_SBMAXGOALMIN         0.0f
271 #define EXPP_OBJECT_SBMAXGOALMAX         1.0f
272 #define EXPP_OBJECT_SBDEFGOALMIN         0.0f
273 #define EXPP_OBJECT_SBDEFGOALMAX         1.0f
274 #define EXPP_OBJECT_SBINSPRINGMIN        0.0f
275 #define EXPP_OBJECT_SBINSPRINGMAX      0.999f
276 #define EXPP_OBJECT_SBINFRICTMIN         0.0f
277 #define EXPP_OBJECT_SBINFRICTMAX        10.0f
278 #define EXPP_OBJECT_DUPFACESCALEFACMIN  0.001f
279 #define EXPP_OBJECT_DUPFACESCALEFACMAX  10000.0f
280
281 /*****************************************************************************/
282 /* Python API function prototypes for the Blender module.                */
283 /*****************************************************************************/
284 static PyObject *M_Object_New( PyObject * self, PyObject * args );
285 PyObject *M_Object_Get( PyObject * self, PyObject * args );
286 static PyObject *M_Object_GetSelected( PyObject * self );
287 static PyObject *M_Object_Duplicate( PyObject * self, PyObject * args, PyObject *kwd);
288
289 /* HELPER FUNCTION FOR PARENTING */
290 static PyObject *internal_makeParent(Object *parent, PyObject *py_child, int partype, int noninverse, int fast, int v1, int v2, int v3, char *bonename);
291
292 /*****************************************************************************/
293 /* The following string definitions are used for documentation strings.  */
294 /* In Python these will be written to the console when doing a           */
295 /* Blender.Object.__doc__                                                */
296 /*****************************************************************************/
297 char M_Object_doc[] = "The Blender Object module\n\n\
298 This module provides access to **Object Data** in Blender.\n";
299
300 char M_Object_New_doc[] =
301         "(type) - Add a new object of type 'type' in the current scene";
302
303 char M_Object_Get_doc[] =
304         "(name) - return the object with the name 'name', returns None if not\
305         found.\n\
306         If 'name' is not specified, it returns a list of all objects in the\n\
307         current scene.";
308
309 char M_Object_GetSelected_doc[] =
310         "() - Returns a list of selected Objects in the active layer(s)\n\
311 The active object is the first in the list, if visible";
312
313 char M_Object_Duplicate_doc[] =
314         "(linked) - Duplicate all selected, visible objects in the current scene";
315
316
317 /*****************************************************************************/
318 /* Python method structure definition for Blender.Object module:         */
319 /*****************************************************************************/
320 struct PyMethodDef M_Object_methods[] = {
321         {"New", ( PyCFunction ) M_Object_New, METH_VARARGS,
322          M_Object_New_doc},
323         {"Get", ( PyCFunction ) M_Object_Get, METH_VARARGS,
324          M_Object_Get_doc},
325         {"GetSelected", ( PyCFunction ) M_Object_GetSelected, METH_NOARGS,
326          M_Object_GetSelected_doc},
327         {"Duplicate", ( PyCFunction ) M_Object_Duplicate, METH_VARARGS | METH_KEYWORDS,
328          M_Object_Duplicate_doc},
329         {NULL, NULL, 0, NULL}
330 };
331
332
333 /*****************************************************************************/
334 /* Python BPy_Object methods declarations:                                 */
335 /*****************************************************************************/
336 static int setupSB(Object* ob); /*Make sure Softbody Pointer is initialized */
337 static int setupPI(Object* ob);
338
339 static PyObject *Object_buildParts( BPy_Object * self );
340 static PyObject *Object_clearIpo( BPy_Object * self );
341 static PyObject *Object_clrParent( BPy_Object * self, PyObject * args );
342 static PyObject *Object_clearTrack( BPy_Object * self, PyObject * args );
343 static PyObject *Object_getData(BPy_Object *self, PyObject *args, PyObject *kwd);
344 static PyObject *Object_getDeltaLocation( BPy_Object * self );
345 static PyObject *Object_getDrawMode( BPy_Object * self );
346 static PyObject *Object_getDrawType( BPy_Object * self );
347 static PyObject *Object_GetEuler( BPy_Object * self, PyObject * args );
348 static PyObject *Object_getInverseMatrix( BPy_Object * self );
349 static PyObject *Object_getIpo( BPy_Object * self );
350 static PyObject *Object_getLocation( BPy_Object * self, PyObject * args );
351 static PyObject *Object_getMaterials( BPy_Object * self, PyObject * args );
352 static PyObject *Object_getMatrix( BPy_Object * self, PyObject * args );
353 static PyObject *Object_getParent( BPy_Object * self );
354 static PyObject *Object_getParentBoneName( BPy_Object * self );
355 static int Object_setParentBoneName( BPy_Object * self, PyObject * value );
356 static PyObject *Object_getSize( BPy_Object * self, PyObject * args );
357 static PyObject *Object_getTimeOffset( BPy_Object * self );
358 static PyObject *Object_getTracked( BPy_Object * self );
359 static PyObject *Object_getType( BPy_Object * self );
360 static PyObject *Object_getBoundBox( BPy_Object * self, PyObject *args );
361 static PyObject *Object_getBoundBox_noargs( BPy_Object * self );
362 static PyObject *Object_getAction( BPy_Object * self );
363 static PyObject *Object_getPose( BPy_Object * self );
364 static PyObject *Object_evaluatePose( BPy_Object * self, PyObject *args );
365 static PyObject *Object_getSelected( BPy_Object * self );
366 static PyObject *Object_makeDisplayList( BPy_Object * self );
367 static PyObject *Object_link( BPy_Object * self, PyObject * args );
368 static PyObject *Object_makeParent( BPy_Object * self, PyObject * args );
369 static PyObject *Object_join( BPy_Object * self, PyObject * args );
370 static PyObject *Object_makeParentDeform( BPy_Object * self, PyObject * args );
371 static PyObject *Object_makeParentVertex( BPy_Object * self, PyObject * args );
372 static PyObject *Object_makeParentBone( BPy_Object * self, PyObject * args );
373 static PyObject *Object_materialUsage( void );
374 static PyObject *Object_getDupliObjects ( BPy_Object * self);
375 static PyObject *Object_getEffects( BPy_Object * self );
376 static PyObject *Object_setDeltaLocation( BPy_Object * self, PyObject * args );
377 static PyObject *Object_SetDrawMode( BPy_Object * self, PyObject * args );
378 static PyObject *Object_SetDrawType( BPy_Object * self, PyObject * args );
379 static PyObject *Object_SetEuler( BPy_Object * self, PyObject * args );
380 static PyObject *Object_SetMatrix( BPy_Object * self, PyObject * args );
381 static PyObject *Object_SetIpo( BPy_Object * self, PyObject * args );
382 static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args );
383 static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args );
384 static PyObject *Object_insertCurrentPoseKey( BPy_Object * self, PyObject * args );
385 static PyObject *Object_setConstraintInfluenceForBone( BPy_Object * self, PyObject * args );
386 static PyObject *Object_setLocation( BPy_Object * self, PyObject * args );
387 static PyObject *Object_setMaterials( BPy_Object * self, PyObject * args );
388 static PyObject *Object_setSize( BPy_Object * self, PyObject * args );
389 static PyObject *Object_setTimeOffset( BPy_Object * self, PyObject * args );
390 static PyObject *Object_makeTrack( BPy_Object * self, PyObject * args );
391 static PyObject *Object_shareFrom( BPy_Object * self, PyObject * args );
392 static PyObject *Object_Select( BPy_Object * self, PyObject * args );
393 static PyObject *Object_getAllProperties( BPy_Object * self );
394 static PyObject *Object_addProperty( BPy_Object * self, PyObject * args );
395 static PyObject *Object_removeProperty( BPy_Object * self, PyObject * args );
396 static PyObject *Object_getProperty( BPy_Object * self, PyObject * args );
397 static PyObject *Object_removeAllProperties( BPy_Object * self );
398 static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
399                                              PyObject * args );
400 static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * value );
401 static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args );
402 static PyObject *Object_clearScriptLinks( BPy_Object * self, PyObject *args );
403 static PyObject *Object_getPIStrength( BPy_Object * self );
404 static PyObject *Object_setPIStrength( BPy_Object * self, PyObject * args );
405 static PyObject *Object_getPIFalloff( BPy_Object * self );
406 static PyObject *Object_setPIFalloff( BPy_Object * self, PyObject * args );
407 static PyObject *Object_getPIMaxDist( BPy_Object * self );
408 static PyObject *Object_setPIMaxDist( BPy_Object * self, PyObject * args );
409 static PyObject *Object_getPIUseMaxDist( BPy_Object * self );
410 static PyObject *Object_SetPIUseMaxDist( BPy_Object * self, PyObject * args );
411 static PyObject *Object_getPIType( BPy_Object * self );
412 static PyObject *Object_SetPIType( BPy_Object * self, PyObject * args );
413 static PyObject *Object_getPIPerm( BPy_Object * self );
414 static PyObject *Object_SetPIPerm( BPy_Object * self, PyObject * args );
415 static PyObject *Object_getPIRandomDamp( BPy_Object * self );
416 static PyObject *Object_setPIRandomDamp( BPy_Object * self, PyObject * args );
417 static PyObject *Object_getPISurfaceDamp( BPy_Object * self );
418 static PyObject *Object_SetPISurfaceDamp( BPy_Object * self, PyObject * args );
419 static PyObject *Object_getPIDeflection( BPy_Object * self );
420 static PyObject *Object_SetPIDeflection( BPy_Object * self, PyObject * args );
421
422 static int Object_setRBMass( BPy_Object * self, PyObject * args );
423 static int Object_setRBFlags( BPy_Object * self, PyObject * args );
424 static int Object_setRBShapeBoundType( BPy_Object * self, PyObject * args );
425
426 static PyObject *Object_getSBMass( BPy_Object * self );
427 static PyObject *Object_setSBMass( BPy_Object * self, PyObject * args );
428 static PyObject *Object_getSBGravity( BPy_Object * self );
429 static PyObject *Object_setSBGravity( BPy_Object * self, PyObject * args );
430 static PyObject *Object_getSBFriction( BPy_Object * self );
431 static PyObject *Object_setSBFriction( BPy_Object * self, PyObject * args );
432 static PyObject *Object_getSBErrorLimit( BPy_Object * self );
433 static PyObject *Object_setSBErrorLimit( BPy_Object * self, PyObject * args );
434 static PyObject *Object_getSBGoalSpring( BPy_Object * self );
435 static PyObject *Object_setSBGoalSpring( BPy_Object * self, PyObject * args );
436 static PyObject *Object_getSBGoalFriction( BPy_Object * self );
437 static PyObject *Object_setSBGoalFriction( BPy_Object * self, PyObject * args );
438 static PyObject *Object_getSBMinGoal( BPy_Object * self );
439 static PyObject *Object_setSBMinGoal( BPy_Object * self, PyObject * args );
440 static PyObject *Object_getSBMaxGoal( BPy_Object * self );
441 static PyObject *Object_setSBMaxGoal( BPy_Object * self, PyObject * args );
442 static PyObject *Object_getSBInnerSpring( BPy_Object * self );
443 static PyObject *Object_setSBInnerSpring( BPy_Object * self, PyObject * args );
444 static PyObject *Object_getSBInnerSpringFriction( BPy_Object * self );
445 static PyObject *Object_setSBInnerSpringFriction( BPy_Object * self, PyObject * args );
446
447 static PyObject *Object_isSB( BPy_Object * self );
448 static PyObject *Object_getSBDefaultGoal( BPy_Object * self );
449 static PyObject *Object_setSBDefaultGoal( BPy_Object * self, PyObject * args );
450 static PyObject *Object_getSBUseGoal( BPy_Object * self );
451 static PyObject *Object_SetSBUseGoal( BPy_Object * self, PyObject * args );
452 static PyObject *Object_getSBUseEdges( BPy_Object * self );
453 static PyObject *Object_SetSBUseEdges( BPy_Object * self, PyObject * args );
454 static PyObject *Object_getSBStiffQuads( BPy_Object * self );
455 static PyObject *Object_SetSBStiffQuads( BPy_Object * self, PyObject * args );
456 static PyObject *Object_insertShapeKey(BPy_Object * self);
457 static PyObject *Object_copyNLA( BPy_Object * self, PyObject * args );
458 static PyObject *Object_convertActionToStrip( BPy_Object * self );
459 static PyObject *Object_copy(BPy_Object * self); /* __copy__ */
460 static PyObject *Object_trackAxis(BPy_Object * self);
461 static PyObject *Object_upAxis(BPy_Object * self);
462
463 /*****************************************************************************/
464 /* Python BPy_Object methods table:                                        */
465 /*****************************************************************************/
466 static PyMethodDef BPy_Object_methods[] = {
467         /* name, method, flags, doc */
468         {"buildParts", ( PyCFunction ) Object_buildParts, METH_NOARGS,
469          "Recalcs particle system (if any), (depricated, will always return an empty list in version 2.46)"},
470         {"getIpo", ( PyCFunction ) Object_getIpo, METH_NOARGS,
471          "Returns the ipo of this object (if any) "},
472         {"clrParent", ( PyCFunction ) Object_clrParent, METH_VARARGS,
473          "Clears parent object. Optionally specify:\n\
474 mode\n\tnonzero: Keep object transform\nfast\n\t>0: Don't update scene \
475 hierarchy (faster)"},
476         {"clearTrack", ( PyCFunction ) Object_clearTrack, METH_VARARGS,
477          "Make this object not track another anymore. Optionally specify:\n\
478 mode\n\t2: Keep object transform\nfast\n\t>0: Don't update scene \
479 hierarchy (faster)"},
480         {"getData", ( PyCFunction ) Object_getData, METH_VARARGS | METH_KEYWORDS,
481          "(name_only = 0, mesh = 0) - Returns the datablock object containing the object's \
482 data, e.g. Mesh.\n\
483 If 'name_only' is nonzero or True, only the name of the datablock is returned"},
484         {"getDeltaLocation", ( PyCFunction ) Object_getDeltaLocation,
485          METH_NOARGS,
486          "Returns the object's delta location (x, y, z)"},
487         {"getDrawMode", ( PyCFunction ) Object_getDrawMode, METH_NOARGS,
488          "Returns the object draw modes"},
489         {"getDrawType", ( PyCFunction ) Object_getDrawType, METH_NOARGS,
490          "Returns the object draw type"},
491         {"getAction", ( PyCFunction ) Object_getAction, METH_NOARGS,
492          "Returns the active action for this object"},
493         {"evaluatePose", ( PyCFunction ) Object_evaluatePose, METH_VARARGS,
494         "(framenum) - Updates the pose to a certain frame number when the Object is\
495         bound to an Action"},
496         {"getPose", ( PyCFunction ) Object_getPose, METH_NOARGS,
497         "() - returns the pose from an object if it exists, else None"},
498         {"isSelected", ( PyCFunction ) Object_getSelected, METH_NOARGS,
499          "Return a 1 or 0 depending on whether the object is selected"},
500         {"getEuler", ( PyCFunction ) Object_GetEuler, METH_VARARGS,
501          "(space = 'localspace' / 'worldspace') - Returns the object's rotation as Euler rotation vector\n\
502 (rotX, rotY, rotZ)"},
503         {"getInverseMatrix", ( PyCFunction ) Object_getInverseMatrix,
504          METH_NOARGS,
505          "Returns the object's inverse matrix"},
506         {"getLocation", ( PyCFunction ) Object_getLocation, METH_VARARGS,
507          "(space = 'localspace' / 'worldspace') - Returns the object's location (x, y, z)\n\
508 "},
509         {"getMaterials", ( PyCFunction ) Object_getMaterials, METH_VARARGS,
510          "(i = 0) - Returns list of materials assigned to the object.\n\
511 if i is nonzero, empty slots are not ignored: they are returned as None's."},
512         {"getMatrix", ( PyCFunction ) Object_getMatrix, METH_VARARGS,
513          "(str = 'worldspace') - Returns the object matrix.\n\
514 (str = 'worldspace') - the desired matrix: worldspace (default), localspace\n\
515 or old_worldspace.\n\
516 \n\
517 'old_worldspace' was the only behavior before Blender 2.34.  With it the\n\
518 matrix is not updated for changes made by the script itself\n\
519 (like obj.LocX = 10) until a redraw happens, either called by the script or\n\
520 automatic when the script finishes."},
521         {"getName", ( PyCFunction ) GenericLib_getName, METH_NOARGS,
522          "Returns the name of the object"},
523         {"getParent", ( PyCFunction ) Object_getParent, METH_NOARGS,
524          "Returns the object's parent object"},
525         {"getParentBoneName", ( PyCFunction ) Object_getParentBoneName, METH_NOARGS,
526          "Returns None, or the 'sub-name' of the parent (eg. Bone name)"},
527         {"getSize", ( PyCFunction ) Object_getSize, METH_VARARGS,
528          "(space = 'localspace' / 'worldspace') - Returns the object's size (x, y, z)"},
529         {"getTimeOffset", ( PyCFunction ) Object_getTimeOffset, METH_NOARGS,
530          "Returns the object's time offset"},
531         {"getTracked", ( PyCFunction ) Object_getTracked, METH_NOARGS,
532          "Returns the object's tracked object"},
533         {"getType", ( PyCFunction ) Object_getType, METH_NOARGS,
534          "Returns type of string of Object"},
535 /* Particle Interaction */
536          
537         {"getPIStrength", ( PyCFunction ) Object_getPIStrength, METH_NOARGS,
538          "Returns Particle Interaction Strength"},
539         {"setPIStrength", ( PyCFunction ) Object_setPIStrength, METH_VARARGS,
540          "Sets Particle Interaction Strength"},
541         {"getPIFalloff", ( PyCFunction ) Object_getPIFalloff, METH_NOARGS,
542          "Returns Particle Interaction Falloff"},
543         {"setPIFalloff", ( PyCFunction ) Object_setPIFalloff, METH_VARARGS,
544          "Sets Particle Interaction Falloff"},
545         {"getPIMaxDist", ( PyCFunction ) Object_getPIMaxDist, METH_NOARGS,
546          "Returns Particle Interaction Max Distance"},
547         {"setPIMaxDist", ( PyCFunction ) Object_setPIMaxDist, METH_VARARGS,
548          "Sets Particle Interaction Max Distance"},
549         {"getPIUseMaxDist", ( PyCFunction ) Object_getPIUseMaxDist, METH_NOARGS,
550          "Returns bool for Use Max Distace in Particle Interaction "},
551         {"setPIUseMaxDist", ( PyCFunction ) Object_SetPIUseMaxDist, METH_VARARGS,
552          "Sets if Max Distance should be used in Particle Interaction"},
553         {"getPIType", ( PyCFunction ) Object_getPIType, METH_NOARGS,
554          "Returns Particle Interaction Type"},
555         {"setPIType", ( PyCFunction ) Object_SetPIType, METH_VARARGS,
556          "sets Particle Interaction Type"},
557         {"getPIPerm", ( PyCFunction ) Object_getPIPerm, METH_NOARGS,
558          "Returns Particle Interaction Permiability"},
559         {"setPIPerm", ( PyCFunction ) Object_SetPIPerm, METH_VARARGS,
560          "Sets Particle Interaction Permiability"},
561         {"getPISurfaceDamp", ( PyCFunction ) Object_getPISurfaceDamp, METH_NOARGS,
562          "Returns Particle Interaction Surface Damping"},
563         {"setPISurfaceDamp", ( PyCFunction ) Object_SetPISurfaceDamp, METH_VARARGS,
564          "Sets Particle Interaction Surface Damping"},
565         {"getPIRandomDamp", ( PyCFunction ) Object_getPIRandomDamp, METH_NOARGS,
566          "Returns Particle Interaction Random Damping"},
567         {"setPIRandomDamp", ( PyCFunction ) Object_setPIRandomDamp, METH_VARARGS,
568          "Sets Particle Interaction Random Damping"},
569         {"getPIDeflection", ( PyCFunction ) Object_getPIDeflection, METH_NOARGS,
570          "Returns Particle Interaction Deflection"},
571         {"setPIDeflection", ( PyCFunction ) Object_SetPIDeflection, METH_VARARGS,
572          "Sets Particle Interaction Deflection"},  
573
574 /* Softbody */
575
576         {"isSB", ( PyCFunction ) Object_isSB, METH_NOARGS,
577          "True if object is a soft body"},
578         {"getSBMass", ( PyCFunction ) Object_getSBMass, METH_NOARGS,
579          "Returns SB Mass"},
580         {"setSBMass", ( PyCFunction ) Object_setSBMass, METH_VARARGS,
581          "Sets SB Mass"}, 
582         {"getSBGravity", ( PyCFunction ) Object_getSBGravity, METH_NOARGS,
583          "Returns SB Gravity"},
584         {"setSBGravity", ( PyCFunction ) Object_setSBGravity, METH_VARARGS,
585          "Sets SB Gravity"}, 
586         {"getSBFriction", ( PyCFunction ) Object_getSBFriction, METH_NOARGS,
587          "Returns SB Friction"},
588         {"setSBFriction", ( PyCFunction ) Object_setSBFriction, METH_VARARGS,
589          "Sets SB Friction"}, 
590         {"getSBErrorLimit", ( PyCFunction ) Object_getSBErrorLimit, METH_NOARGS,
591          "Returns SB ErrorLimit"},
592         {"setSBErrorLimit", ( PyCFunction ) Object_setSBErrorLimit, METH_VARARGS,
593          "Sets SB ErrorLimit"}, 
594         {"getSBGoalSpring", ( PyCFunction ) Object_getSBGoalSpring, METH_NOARGS,
595          "Returns SB GoalSpring"},
596         {"setSBGoalSpring", ( PyCFunction ) Object_setSBGoalSpring, METH_VARARGS,
597          "Sets SB GoalSpring"}, 
598         {"getSBGoalFriction", ( PyCFunction ) Object_getSBGoalFriction, METH_NOARGS,
599          "Returns SB GoalFriction"},
600         {"setSBGoalFriction", ( PyCFunction ) Object_setSBGoalFriction, METH_VARARGS,
601          "Sets SB GoalFriction"}, 
602         {"getSBMinGoal", ( PyCFunction ) Object_getSBMinGoal, METH_NOARGS,
603          "Returns SB MinGoal"},
604         {"setSBMinGoal", ( PyCFunction ) Object_setSBMinGoal, METH_VARARGS,
605          "Sets SB MinGoal "}, 
606         {"getSBMaxGoal", ( PyCFunction ) Object_getSBMaxGoal, METH_NOARGS,
607          "Returns SB MaxGoal"},
608         {"setSBMaxGoal", ( PyCFunction ) Object_setSBMaxGoal, METH_VARARGS,
609          "Sets SB MaxGoal"},  
610         {"getSBInnerSpring", ( PyCFunction ) Object_getSBInnerSpring, METH_NOARGS,
611          "Returns SB InnerSpring"},
612         {"setSBInnerSpring", ( PyCFunction ) Object_setSBInnerSpring, METH_VARARGS,
613          "Sets SB InnerSpring"},         
614         {"getSBInnerSpringFriction", ( PyCFunction ) Object_getSBInnerSpringFriction, METH_NOARGS,
615          "Returns SB InnerSpringFriction"},
616         {"setSBInnerSpringFriction", ( PyCFunction ) Object_setSBInnerSpringFriction, METH_VARARGS,
617          "Sets SB InnerSpringFriction"},        
618         {"getSBDefaultGoal", ( PyCFunction ) Object_getSBDefaultGoal, METH_NOARGS,
619          "Returns SB DefaultGoal"},
620         {"setSBDefaultGoal", ( PyCFunction ) Object_setSBDefaultGoal, METH_VARARGS,
621          "Sets SB DefaultGoal"},                 
622         {"getSBUseGoal", ( PyCFunction ) Object_getSBUseGoal, METH_NOARGS,
623          "Returns SB UseGoal"},
624         {"setSBUseGoal", ( PyCFunction ) Object_SetSBUseGoal, METH_VARARGS,
625          "Sets SB UseGoal"}, 
626         {"getSBUseEdges", ( PyCFunction ) Object_getSBUseEdges, METH_NOARGS,
627          "Returns SB UseEdges"},
628         {"setSBUseEdges", ( PyCFunction ) Object_SetSBUseEdges, METH_VARARGS,
629          "Sets SB UseEdges"}, 
630         {"getSBStiffQuads", ( PyCFunction ) Object_getSBStiffQuads, METH_NOARGS,
631          "Returns SB StiffQuads"},
632         {"setSBStiffQuads", ( PyCFunction ) Object_SetSBStiffQuads, METH_VARARGS,
633          "Sets SB StiffQuads"},
634         {"getBoundBox", ( PyCFunction ) Object_getBoundBox, METH_VARARGS,
635          "Returns the object's bounding box"},
636         {"makeDisplayList", ( PyCFunction ) Object_makeDisplayList, METH_NOARGS,
637          "Update this object's Display List. Some changes like turning\n\
638 'SubSurf' on for a mesh need this method (followed by a Redraw) to\n\
639 show the changes on the 3d window."},
640         {"link", ( PyCFunction ) Object_link, METH_VARARGS,
641          "Links Object with data provided in the argument. The data must\n\
642 match the Object's type, so you cannot link a Lamp to a Mesh type object."},
643         {"makeParent", ( PyCFunction ) Object_makeParent, METH_VARARGS,
644          "Makes the object the parent of the objects provided in the\n\
645 argument which must be a list of valid Objects. Optional extra arguments:\n\
646 mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
647 fast:\n\t0: update scene hierarchy automatically\n\t\
648 don't update scene hierarchy (faster). In this case, you must\n\t\
649 explicitly update the Scene hierarchy."},
650         {"join", ( PyCFunction ) Object_join, METH_VARARGS,
651          "(object_list) - Joins the objects in object list of the same type, into this object."},
652         {"makeParentDeform", ( PyCFunction ) Object_makeParentDeform, METH_VARARGS,
653          "Makes the object the deformation parent of the objects provided in the \n\
654 argument which must be a list of valid Objects. Optional extra arguments:\n\
655 mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
656 fast:\n\t0: update scene hierarchy automatically\n\t\
657 don't update scene hierarchy (faster). In this case, you must\n\t\
658 explicitly update the Scene hierarchy."},
659         {"makeParentVertex", ( PyCFunction ) Object_makeParentVertex, METH_VARARGS,
660          "Makes the object the vertex parent of the objects provided in the \n\
661 argument which must be a list of valid Objects. \n\
662 The second argument is a tuple of 1 or 3 positive integers which corresponds \
663 to the index of the vertex you are parenting to.\n\
664 Optional extra arguments:\n\
665 mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
666 fast:\n\t0: update scene hierarchy automatically\n\t\
667 don't update scene hierarchy (faster). In this case, you must\n\t\
668 explicitly update the Scene hierarchy."},
669         {"makeParentBone", ( PyCFunction ) Object_makeParentBone, METH_VARARGS,
670          "Makes this armature objects bone, the parent of the objects provided in the \n\
671 argument which must be a list of valid Objects. Optional extra arguments:\n\
672 mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
673 fast:\n\t0: update scene hierarchy automatically\n\t\
674 don't update scene hierarchy (faster). In this case, you must\n\t\
675 explicitely update the Scene hierarchy."},
676
677         {"materialUsage", ( PyCFunction ) Object_materialUsage, METH_NOARGS,
678          "Determines the way the material is used and returns status.\n\
679 Possible arguments (provide as strings):\n\
680 \tData:   Materials assigned to the object's data are shown. (default)\n\
681 \tObject: Materials assigned to the object are shown."},
682         {"setDeltaLocation", ( PyCFunction ) Object_setDeltaLocation,
683          METH_VARARGS,
684          "Sets the object's delta location which must be a vector triple."},
685         {"setDrawMode", ( PyCFunction ) Object_SetDrawMode, METH_VARARGS,
686          "Sets the object's drawing mode. The argument can be a sum of:\n\
687 2: axis\n4: texspace\n8: drawname\n16: drawimage\n32: drawwire\n64: drawxray\n128: drawtransp"},
688         {"setDrawType", ( PyCFunction ) Object_SetDrawType, METH_VARARGS,
689          "Sets the object's drawing type. The argument must be one of:\n\
690 1: Bounding box\n2: Wire\n3: Solid\n4: Shaded\n5: Textured"},
691         {"setEuler", ( PyCFunction ) Object_SetEuler, METH_VARARGS,
692          "Set the object's rotation according to the specified Euler\n\
693 angles. The argument must be a vector triple"},
694         {"setMatrix", ( PyCFunction ) Object_SetMatrix, METH_VARARGS,
695          "Set and apply a new local matrix for the object"},
696         {"setLocation", ( PyCFunction ) Object_setLocation, METH_VARARGS,
697          "Set the object's location. The first argument must be a vector\n\
698 triple."},
699         {"setMaterials", ( PyCFunction ) Object_setMaterials, METH_VARARGS,
700          "Sets materials. The argument must be a list of valid material\n\
701 objects."},
702         {"setName", ( PyCFunction ) GenericLib_setName_with_method, METH_VARARGS,
703          "Sets the name of the object"},
704         {"setSize", ( PyCFunction ) Object_setSize, METH_VARARGS,
705          "Set the object's size. The first argument must be a vector\n\
706 triple."},
707         {"setTimeOffset", ( PyCFunction ) Object_setTimeOffset, METH_VARARGS,
708          "Set the object's time offset."},
709         {"makeTrack", ( PyCFunction ) Object_makeTrack, METH_VARARGS,
710          "(trackedobj, fast = 0) - Make this object track another.\n\
711          (trackedobj) - the object that will be tracked.\n\
712          (fast = 0) - if 0: update the scene hierarchy automatically.  If you\n\
713          set 'fast' to a nonzero value, don't forget to update the scene yourself\n\
714          (see scene.update())."},
715         {"shareFrom", ( PyCFunction ) Object_shareFrom, METH_VARARGS,
716          "Link data of self with object specified in the argument. This\n\
717 works only if self and the object specified are of the same type."},
718         {"select", ( PyCFunction ) Object_Select, METH_VARARGS,
719          "( 1 or 0 )  - Set the selected state of the object.\n\
720    1 is selected, 0 not selected "},
721         {"setIpo", ( PyCFunction ) Object_SetIpo, METH_VARARGS,
722          "(Blender Ipo) - Sets the object's ipo"},
723         {"clearIpo", ( PyCFunction ) Object_clearIpo, METH_NOARGS,
724          "() - Unlink ipo from this object"},
725
726          {"insertIpoKey", ( PyCFunction ) Object_insertIpoKey, METH_VARARGS,
727          "( Object IPO type ) - Inserts a key into IPO"},
728          {"insertPoseKey", ( PyCFunction ) Object_insertPoseKey, METH_VARARGS,
729          "( Object Pose type ) - Inserts a key into Action"},
730          {"insertCurrentPoseKey", ( PyCFunction ) Object_insertCurrentPoseKey, METH_VARARGS,
731          "( Object Pose type ) - Inserts a key into Action based on current pose"},
732          {"setConstraintInfluenceForBone", ( PyCFunction ) Object_setConstraintInfluenceForBone, METH_VARARGS,
733           "(  ) - sets a constraint influence for a certain bone in this (armature)object."},
734          {"copyNLA", ( PyCFunction ) Object_copyNLA, METH_VARARGS,
735           "(  ) - copies all NLA strips from another object to this object."},
736         {"convertActionToStrip", ( PyCFunction ) Object_convertActionToStrip, METH_NOARGS,
737          "(  ) - copies all NLA strips from another object to this object."},
738         {"getAllProperties", ( PyCFunction ) Object_getAllProperties, METH_NOARGS,
739          "() - Get all the properties from this object"},
740         {"addProperty", ( PyCFunction ) Object_addProperty, METH_VARARGS,
741          "() - Add a property to this object"},
742         {"removeProperty", ( PyCFunction ) Object_removeProperty, METH_VARARGS,
743          "() - Remove a property from  this object"},
744         {"getProperty", ( PyCFunction ) Object_getProperty, METH_VARARGS,
745          "() - Get a property from this object by name"},
746         {"removeAllProperties", ( PyCFunction ) Object_removeAllProperties,
747          METH_NOARGS,
748          "() - removeAll a properties from this object"},
749         {"copyAllPropertiesTo", ( PyCFunction ) Object_copyAllPropertiesTo,
750          METH_VARARGS,
751          "() - copy all properties from this object to another object"},
752         {"getScriptLinks", ( PyCFunction ) Object_getScriptLinks, METH_O,
753          "(eventname) - Get a list of this object's scriptlinks (Text names) "
754          "of the given type\n"
755          "(eventname) - string: FrameChanged, Redraw or Render."},
756         {"addScriptLink", ( PyCFunction ) Object_addScriptLink, METH_VARARGS,
757          "(text, evt) - Add a new object scriptlink.\n"
758          "(text) - string: an existing Blender Text name;\n"
759          "(evt) string: FrameChanged, Redraw or Render."},
760         {"clearScriptLinks", ( PyCFunction ) Object_clearScriptLinks,
761          METH_VARARGS,
762          "() - Delete all scriptlinks from this object.\n"
763          "([s1<,s2,s3...>]) - Delete specified scriptlinks from this object."},
764         {"insertShapeKey", ( PyCFunction ) Object_insertShapeKey, METH_NOARGS,
765          "() - Insert a Shape Key in the current object"},
766         {"__copy__", ( PyCFunction ) Object_copy, METH_NOARGS,
767          "() - Return a copy of this object."},
768         {"copy", ( PyCFunction ) Object_copy, METH_NOARGS,
769          "() - Return a copy of this object."},
770         {NULL, NULL, 0, NULL}
771 };
772
773 /*****************************************************************************/
774 /* PythonTypeObject callback function prototypes                         */
775 /*****************************************************************************/
776 static void Object_dealloc( BPy_Object * obj );
777 static PyObject *Object_repr( BPy_Object * obj );
778 static int Object_compare( BPy_Object * a, BPy_Object * b );
779
780 /*****************************************************************************/
781 /* Function:                      M_Object_New                           */
782 /* Python equivalent:     Blender.Object.New                             */
783 /*****************************************************************************/
784
785 /*
786  * Note: if this method is called without later linking object data to it, 
787  * errors can be caused elsewhere in Blender.  Future versions of the API
788  * will designate obdata as a parameter to this method to prevent this, and
789  * eventually this method will be deprecated.
790  *
791  * When we can guarantee that objects will always have valid obdata, 
792  * unlink_object() should be edited to remove checks for NULL pointers and
793  * debugging messages.
794  */
795
796 PyObject *M_Object_New( PyObject * self_unused, PyObject * args )
797 {
798         struct Object *object;
799         int type;
800         char *str_type;
801         char *name = NULL;
802         PyObject *py_object;
803         BPy_Object *blen_object;
804
805         if( !PyArg_ParseTuple( args, "s|s", &str_type, &name ) )
806                 return EXPP_ReturnPyObjError( PyExc_TypeError,
807                                 "string expected as argument" );
808
809         if( strcmp( str_type, "Armature" ) == 0 )
810                 type = OB_ARMATURE;
811         else if( strcmp( str_type, "Camera" ) == 0 )
812                 type = OB_CAMERA;
813         else if( strcmp( str_type, "Curve" ) == 0 )
814                 type = OB_CURVE;
815         else if (strcmp (str_type, "Text") == 0)        
816                 type = OB_FONT;
817         else if( strcmp( str_type, "Lamp" ) == 0 )
818                 type = OB_LAMP;
819         else if( strcmp( str_type, "Lattice" ) == 0 )
820                 type = OB_LATTICE;
821         else if( strcmp( str_type, "Mball" ) == 0 )
822                 type = OB_MBALL;
823         else if( strcmp( str_type, "Mesh" ) == 0 )
824                 type = OB_MESH;
825         else if( strcmp( str_type, "Surf" ) == 0 )
826                 type = OB_SURF;
827 /*      else if (strcmp (str_type, "Wave") == 0)        type = OB_WAVE; */
828         else if( strcmp( str_type, "Empty" ) == 0 )
829                 type = OB_EMPTY;
830         else
831                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
832                                 "Unknown type specified" );
833
834         /* Create a new object. */
835         if( name == NULL ) {
836         /* No name is specified, set the name to the type of the object. */
837                 name = str_type;
838         }
839         object = add_only_object(type, name);
840
841         object->flag = 0;
842         object->lay = 1;        /* Layer, by default visible*/
843         object->data = NULL;
844
845         /* user count is incremented in Object_CreatePyObject */
846         object->id.us = 0;
847
848         /* Create a Python object from it. */
849         py_object = Object_CreatePyObject( object );
850         blen_object = (BPy_Object *)py_object;
851
852         /* store the real object type in the PyObject, treat this as an Empty
853          * until it has some obdata */
854         blen_object->realtype = object->type;
855         object->type = OB_EMPTY;
856
857         return py_object;
858 }
859
860 /*****************************************************************************/
861 /* Function:      M_Object_Get                                          */
862 /* Python equivalent:     Blender.Object.Get                            */
863 /*****************************************************************************/
864 PyObject *M_Object_Get( PyObject * self_unused, PyObject * args )
865 {
866         struct Object *object;
867         PyObject *blen_object;
868         char *name = NULL;
869
870         PyArg_ParseTuple( args, "|s", &name );
871
872         if( name != NULL ) {
873                 object = ( Object * ) GetIdFromList( &( G.main->object ), name );
874
875                         /* No object exists with the name specified in the argument name. */
876                 if( !object ){
877                         char buffer[128];
878                         PyOS_snprintf( buffer, sizeof(buffer),
879                                                    "object \"%s\" not found", name);
880                         return EXPP_ReturnPyObjError( PyExc_ValueError,
881                                                                                   buffer );
882                 }
883
884                 /* objects used in pydriver expressions need this */
885                 if (bpy_during_pydriver())
886                         bpy_pydriver_appendToList(object);
887  
888                 return Object_CreatePyObject( object );
889         } else {
890                 /* No argument has been given. Return a list of all objects. */
891                 PyObject *obj_list;
892                 Link *link;
893                 int index;
894
895                 /* do not allow Get() (w/o arguments) inside pydriver, otherwise
896                  * we'd have to update all objects in the DAG */
897                 if (bpy_during_pydriver())
898                         return EXPP_ReturnPyObjError( PyExc_AttributeError,
899                                 "Object.Get requires an argument when used in pydrivers" );
900
901                 obj_list = PyList_New( BLI_countlist( &( G.main->object ) ) );
902
903                 if( !obj_list )
904                         return EXPP_ReturnPyObjError( PyExc_SystemError,
905                                 "List creation failed." );
906
907                 link = G.main->object.first;
908                 index = 0;
909                 while( link ) {
910                         object = ( Object * ) link;
911                         blen_object = Object_CreatePyObject( object );
912                         if( !blen_object ) {
913                                 Py_DECREF( obj_list );
914                                 Py_RETURN_NONE;
915                         }
916                         PyList_SetItem( obj_list, index, blen_object );
917                         index++;
918                         link = link->next;
919                 }
920                 return obj_list;
921         }
922 }
923
924 /*****************************************************************************/
925 /* Function:      M_Object_GetSelected                          */
926 /* Python equivalent:     Blender.Object.GetSelected            */
927 /*****************************************************************************/
928 static PyObject *M_Object_GetSelected( PyObject * self_unused )
929 {
930         PyObject *blen_object;
931         PyObject *list;
932         Base *base_iter;
933
934         list = PyList_New( 0 );
935
936         if( G.vd == NULL ) {
937                 /* No 3d view has been initialized yet, simply return an empty list */
938                 return list;
939         }
940         
941         if( ( G.scene->basact ) &&
942             ( ( G.scene->basact->flag & SELECT ) &&
943               ( G.scene->basact->lay & G.vd->lay ) ) ) {
944
945                 /* Active object is first in the list. */
946                 blen_object = Object_CreatePyObject( G.scene->basact->object );
947                 if( !blen_object ) {
948                         Py_DECREF( list );
949                         Py_RETURN_NONE;
950                 }
951                 PyList_Append( list, blen_object );
952                 Py_DECREF( blen_object );
953         }
954
955         base_iter = G.scene->base.first;
956         while( base_iter ) {
957                 if( ( ( base_iter->flag & SELECT ) &&
958                                 ( base_iter->lay & G.vd->lay ) ) &&
959                                 ( base_iter != G.scene->basact ) ) {
960
961                         blen_object = Object_CreatePyObject( base_iter->object );
962                         if( blen_object ) {
963                                 PyList_Append( list, blen_object );
964                                 Py_DECREF( blen_object );
965                         }
966                 }
967                 base_iter = base_iter->next;
968         }
969         return list;
970 }
971
972
973 /*****************************************************************************/
974 /* Function:                      M_Object_Duplicate                             */
975 /* Python equivalent:     Blender.Object.Duplicate                               */
976 /*****************************************************************************/
977 static PyObject *M_Object_Duplicate( PyObject * self_unused,
978                 PyObject * args, PyObject *kwd )
979 {
980         int dupflag= 0; /* this a flag, passed to adduplicate() and used instead of U.dupflag sp python can set what is duplicated */   
981
982         /* the following variables are bools, if set true they will modify the dupflag to pass to adduplicate() */
983         int mesh_dupe = 0;
984         int surface_dupe = 0;
985         int curve_dupe = 0;
986         int text_dupe = 0;
987         int metaball_dupe = 0;
988         int armature_dupe = 0;
989         int lamp_dupe = 0;
990         int material_dupe = 0;
991         int texture_dupe = 0;
992         int ipo_dupe = 0;
993         
994         static char *kwlist[] = {"mesh", "surface", "curve",
995                         "text", "metaball", "armature", "lamp", "material", "texture", "ipo", NULL};
996         
997         /* duplicating in background causes segfaults */
998         if( G.background == 1 )
999                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1000                                         "cannot duplicate objects in background mode" );
1001         
1002         
1003         if (!PyArg_ParseTupleAndKeywords(args, kwd, "|iiiiiiiiii", kwlist,
1004                 &mesh_dupe, &surface_dupe, &curve_dupe, &text_dupe, &metaball_dupe,
1005                 &armature_dupe, &lamp_dupe, &material_dupe, &texture_dupe, &ipo_dupe))
1006                         return EXPP_ReturnPyObjError( PyExc_TypeError,
1007                                 "expected nothing or bool keywords 'mesh', 'surface', 'curve', 'text', 'metaball', 'armature', 'lamp' 'material', 'texture' and 'ipo' as arguments" );
1008         
1009         /* USER_DUP_ACT for actions is not supported in the UI so dont support it here */
1010         if (mesh_dupe)          dupflag |= USER_DUP_MESH;
1011         if (surface_dupe)       dupflag |= USER_DUP_SURF;
1012         if (curve_dupe)         dupflag |= USER_DUP_CURVE;
1013         if (text_dupe)          dupflag |= USER_DUP_FONT;
1014         if (metaball_dupe)      dupflag |= USER_DUP_MBALL;
1015         if (armature_dupe)      dupflag |= USER_DUP_ARM;
1016         if (lamp_dupe)          dupflag |= USER_DUP_LAMP;
1017         if (material_dupe)      dupflag |= USER_DUP_MAT;
1018         if (texture_dupe)       dupflag |= USER_DUP_TEX;
1019         if (ipo_dupe)           dupflag |= USER_DUP_IPO;
1020         adduplicate(2, dupflag); /* 2 is a mode with no transform and no redraw, Duplicate the current selection, context sensitive */
1021         Py_RETURN_NONE;
1022 }
1023
1024
1025 /*****************************************************************************/
1026 /* Python BPy_Object methods:                                   */
1027 /*****************************************************************************/
1028
1029 static PyObject *Object_buildParts( BPy_Object * self )
1030 {
1031         /* This is now handles by modifiers */
1032         Py_RETURN_NONE;
1033 }
1034
1035 static PyObject *Object_clearIpo( BPy_Object * self )
1036 {
1037         Object *ob = self->object;
1038         Ipo *ipo = ( Ipo * ) ob->ipo;
1039
1040         if( ipo ) {
1041                 ID *id = &ipo->id;
1042                 if( id->us > 0 )
1043                         id->us--;
1044                 ob->ipo = NULL;
1045
1046                 Py_RETURN_TRUE;
1047         }
1048
1049         Py_RETURN_FALSE; /* no ipo found */
1050 }
1051
1052 static PyObject *Object_clrParent( BPy_Object * self, PyObject * args )
1053 {
1054         int mode = 0;
1055         int fast = 0;
1056
1057         if( !PyArg_ParseTuple( args, "|ii", &mode, &fast ) )
1058                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1059                                 "expected one or two optional integers as arguments" );
1060
1061         /* Remove the link only, the object is still in the scene. */
1062         self->object->parent = NULL;
1063
1064         if( mode == 2 ) {
1065                 /* Keep transform */
1066                 apply_obmat( self->object );
1067         }
1068
1069         if( !fast )
1070                 DAG_scene_sort( G.scene );
1071
1072         Py_RETURN_NONE;
1073 }
1074
1075 static PyObject *Object_clearTrack( BPy_Object * self, PyObject * args )
1076 {
1077         int mode = 0;
1078         int fast = 0;
1079
1080         if( !PyArg_ParseTuple( args, "|ii", &mode, &fast ) )
1081                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1082                                 "expected one or two optional integers as arguments" );
1083
1084         /* Remove the link only, the object is still in the scene. */
1085         self->object->track = NULL;
1086
1087         if( mode ) {
1088                 /* Keep transform */
1089                 apply_obmat( self->object );
1090         }
1091
1092         if( !fast )
1093                 DAG_scene_sort( G.scene );
1094
1095         Py_RETURN_NONE;
1096 }
1097
1098 /* adds object data to a Blender object, if object->data = NULL */
1099 int EXPP_add_obdata( struct Object *object )
1100 {
1101         if( object->data != NULL )
1102                 return -1;
1103
1104         switch ( object->type ) {
1105         case OB_ARMATURE:
1106                 /* TODO: Do we need to add something to G? (see the OB_LAMP case) */
1107                 object->data = add_armature( "Armature" );
1108                 break;
1109         case OB_CAMERA:
1110                 /* TODO: Do we need to add something to G? (see the OB_LAMP case) */
1111                 object->data = add_camera( "Camera" );
1112                 break;
1113         case OB_CURVE:
1114                 object->data = add_curve( "Curve", OB_CURVE );
1115                 G.totcurve++;
1116                 break;
1117         case OB_LAMP:
1118                 object->data = add_lamp( "Lamp" );
1119                 G.totlamp++;
1120                 break;
1121         case OB_MESH:
1122                 object->data = add_mesh( "Mesh" );
1123                 G.totmesh++;
1124                 break;
1125         case OB_LATTICE:
1126                 object->data = ( void * ) add_lattice( "Lattice" );
1127                 object->dt = OB_WIRE;
1128                 break;
1129         case OB_MBALL:
1130                 object->data = add_mball( "Meta" );
1131                 break;
1132
1133                 /* TODO the following types will be supported later,
1134                    be sure to update Scene_link when new types are supported
1135                    case OB_SURF:
1136                    object->data = add_curve(OB_SURF);
1137                    G.totcurve++;
1138                    break;
1139                    case OB_FONT:
1140                    object->data = add_curve(OB_FONT);
1141                    break;
1142                    case OB_WAVE:
1143                    object->data = add_wave();
1144                    break;
1145                  */
1146         default:
1147                 break;
1148         }
1149
1150         if( !object->data )
1151                 return -1;
1152
1153         return 0;
1154 }
1155
1156 static PyObject *Object_getDeltaLocation( BPy_Object * self )
1157 {
1158         return Py_BuildValue( "fff", self->object->dloc[0],
1159                         self->object->dloc[1], self->object->dloc[2] );
1160 }
1161
1162 static PyObject *Object_getAction( BPy_Object * self )
1163 {
1164         if( self->object->action )
1165                 return Action_CreatePyObject( self->object->action );
1166         Py_RETURN_NONE;
1167 }
1168
1169 static int Object_setAction( BPy_Object * self, PyObject * value )
1170 {
1171         return GenericLib_assignData(value, (void **) &self->object->action, 0, 1, ID_AC, 0);
1172 }
1173
1174 static PyObject *Object_evaluatePose(BPy_Object *self, PyObject *args)
1175 {
1176         int frame = 1;
1177         if( !PyArg_ParseTuple( args, "i", &frame ) )
1178                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1179                                 "expected int argument" );
1180
1181         frame = EXPP_ClampInt(frame, MINFRAME, MAXFRAME);
1182         G.scene->r.cfra = frame;
1183         do_all_pose_actions(self->object);
1184         where_is_pose (self->object);
1185
1186         Py_RETURN_NONE;
1187 }
1188
1189 static PyObject * Object_getPose(BPy_Object *self)
1190 {
1191         /*if there is no pose will return PyNone*/
1192         return PyPose_FromPose(self->object->pose, self->object->id.name+2);
1193 }
1194
1195 static PyObject *Object_getSelected( BPy_Object * self )
1196 {
1197         Base *base;
1198
1199         base = FIRSTBASE;
1200         while( base ) {
1201                 if( base->object == self->object ) {
1202                         if( base->flag & SELECT ) {
1203                                 Py_RETURN_TRUE;
1204                         } else {
1205                                 Py_RETURN_FALSE;
1206                         }
1207                 }
1208                 base = base->next;
1209         }
1210         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1211                         "could not find object's selection state" );
1212 }
1213
1214 static int Object_setSelect( BPy_Object * self, PyObject * value )
1215 {
1216         Base *base;
1217         int param = PyObject_IsTrue( value );
1218
1219         if( param == -1 )
1220                 return EXPP_ReturnIntError( PyExc_TypeError,
1221                                 "expected True/False or 0/1" );
1222
1223         base = FIRSTBASE;
1224         while( base ) {
1225                 if( base->object == self->object ) {
1226                         if( param ) {
1227                                 base->flag |= SELECT;
1228                                 self->object->flag = (short)base->flag;
1229                                 set_active_base( base );
1230                         } else {
1231                                 base->flag &= ~SELECT;
1232                                 self->object->flag = (short)base->flag;
1233                         }
1234                         break;
1235                 }
1236                 base = base->next;
1237         }
1238         if (base) { /* was the object selected? */
1239                 countall(  );
1240         }
1241         return 0;
1242 }
1243
1244 static PyObject *Object_GetEuler( BPy_Object * self, PyObject * args )
1245 {
1246         char *space = "localspace";     /* default to local */
1247         float eul[3];
1248         
1249         if( !PyArg_ParseTuple( args, "|s", &space ) )
1250                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1251                                 "expected a string or nothing" );
1252         
1253         if( BLI_streq( space, "worldspace" ) ) {        /* Worldspace matrix */
1254                 float mat3[3][3];
1255                 disable_where_script( 1 );
1256                 where_is_object( self->object );
1257                 Mat3CpyMat4(mat3, self->object->obmat);
1258                 Mat3ToEul(mat3, eul);
1259                 disable_where_script( 0 );
1260         } else if( BLI_streq( space, "localspace" ) ) { /* Localspace matrix */
1261                 eul[0] = self->object->rot[0];
1262                 eul[1] = self->object->rot[1];
1263                 eul[2] = self->object->rot[2];
1264         } else {
1265                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1266                                 "expected either nothing, 'localspace' (default) or 'worldspace'" );
1267         }
1268
1269         return ( PyObject * ) newEulerObject( eul, Py_NEW );
1270 }
1271
1272 static PyObject *Object_getInverseMatrix( BPy_Object * self )
1273 {
1274         MatrixObject *inverse =
1275                 ( MatrixObject * ) newMatrixObject( NULL, 4, 4, Py_NEW );
1276         Mat4Invert( (float ( * )[4])*inverse->matrix, self->object->obmat );
1277
1278         return ( ( PyObject * ) inverse );
1279 }
1280
1281 static PyObject *Object_getIpo( BPy_Object * self )
1282 {
1283         struct Ipo *ipo = self->object->ipo;
1284
1285         if( ipo )
1286                 return Ipo_CreatePyObject( ipo );
1287         Py_RETURN_NONE;
1288 }
1289
1290 static PyObject *Object_getLocation( BPy_Object * self, PyObject * args )
1291 {
1292         char *space = "localspace";     /* default to local */
1293         PyObject *attr;
1294         if( !PyArg_ParseTuple( args, "|s", &space ) ) 
1295                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1296                                 "expected a string or nothing" );
1297
1298         if( BLI_streq( space, "worldspace" ) ) {        /* Worldspace matrix */
1299                 disable_where_script( 1 );
1300                 where_is_object( self->object );
1301                 
1302                 attr = Py_BuildValue( "fff",
1303                                         self->object->obmat[3][0],
1304                                         self->object->obmat[3][1],
1305                                         self->object->obmat[3][2] );
1306                 
1307                 disable_where_script( 0 );
1308         } else if( BLI_streq( space, "localspace" ) ) { /* Localspace matrix */
1309                 attr = Py_BuildValue( "fff",
1310                                         self->object->loc[0],
1311                                         self->object->loc[1],
1312                                         self->object->loc[2] );
1313         } else {
1314                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1315                                 "expected either nothing, 'localspace' (default) or 'worldspace'" );
1316         }
1317
1318         return attr;
1319 }
1320
1321 static PyObject *Object_getMaterials( BPy_Object * self, PyObject * args )
1322 {
1323         int all = 0;
1324
1325         if( !PyArg_ParseTuple( args, "|i", &all ) )
1326                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1327                                 "expected an int or nothing" );
1328
1329         return EXPP_PyList_fromMaterialList( self->object->mat,
1330                                                self->object->totcol, all );
1331 }
1332
1333 static PyObject *Object_getParent( BPy_Object * self )
1334 {
1335         return Object_CreatePyObject( self->object->parent );
1336 }
1337
1338 static PyObject *Object_getParentBoneName( BPy_Object * self )
1339 {
1340         if( self->object->parent && self->object->parent->type==OB_ARMATURE && self->object->parsubstr[0] != '\0' )
1341                 return PyString_FromString( self->object->parsubstr );
1342         Py_RETURN_NONE;
1343 }
1344
1345 static int Object_setParentBoneName( BPy_Object * self, PyObject *value )
1346 {
1347         char *bonename;
1348         
1349         if (!PyString_Check(value))
1350                 return EXPP_ReturnIntError( PyExc_TypeError,
1351                                 "expected an int or nothing" );
1352         
1353         if (
1354                 self->object->parent &&
1355                 self->object->parent->type == OB_ARMATURE &&
1356                 self->object->partype == PARBONE
1357         ) {/* its all good */} else
1358                 return EXPP_ReturnIntError( PyExc_RuntimeError,
1359                                 "can only set the parent bone name for objects that already have a bone parent" );
1360         
1361         bonename = PyString_AsString(value);
1362
1363         if (!get_named_bone(self->object->parent->data, bonename))
1364                 return EXPP_ReturnIntError( PyExc_ValueError,
1365                                 "cannot parent to this bone: invalid bone name" );
1366         
1367         strcpy(self->object->parsubstr, bonename);
1368         DAG_scene_sort( G.scene );
1369         return 0;
1370 }
1371
1372 static PyObject *Object_getSize( BPy_Object * self, PyObject * args )
1373 {
1374         char *space = "localspace";     /* default to local */
1375         PyObject *attr;
1376         if( !PyArg_ParseTuple( args, "|s", &space ) )
1377                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1378                                         "expected a string or nothing" );
1379
1380         if( BLI_streq( space, "worldspace" ) ) {        /* Worldspace matrix */
1381                 float rot[3];
1382                 float mat[3][3], imat[3][3], tmat[3][3];
1383                 disable_where_script( 1 );
1384                 where_is_object( self->object );
1385                 
1386                 Mat3CpyMat4(mat, self->object->obmat);
1387                 
1388                 /* functionality copied from editobject.c apply_obmat */
1389                 Mat3ToEul(mat, rot);
1390                 EulToMat3(rot, tmat);
1391                 Mat3Inv(imat, tmat);
1392                 Mat3MulMat3(tmat, imat, mat);
1393                 
1394                 attr = Py_BuildValue( "fff",
1395                                         tmat[0][0],
1396                                         tmat[1][1],
1397                                         tmat[2][2] );
1398                 disable_where_script( 0 );
1399         } else if( BLI_streq( space, "localspace" ) ) { /* Localspace matrix */
1400                 attr = Py_BuildValue( "fff",
1401                                         self->object->size[0],
1402                                         self->object->size[1],
1403                                         self->object->size[2] );
1404         } else {
1405                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1406                         "expected either nothing, 'localspace' (default) or 'worldspace'" );
1407         }
1408         return attr;
1409 }
1410
1411 static PyObject *Object_getTimeOffset( BPy_Object * self )
1412 {
1413         return PyFloat_FromDouble ( (double) self->object->sf );
1414 }
1415
1416 static PyObject *Object_getTracked( BPy_Object * self )
1417 {
1418         return Object_CreatePyObject( self->object->track );
1419 }
1420
1421 static PyObject *Object_getType( BPy_Object * self )
1422 {
1423         char *str;
1424         int type = self->object->type;
1425         
1426         /* if object not yet linked to data, return the stored type */
1427         if( self->realtype != OB_EMPTY )
1428                 type = self->realtype;
1429         
1430         switch ( type ) {
1431         case OB_ARMATURE:
1432                 str = "Armature";
1433                 break;
1434         case OB_CAMERA:
1435                 str = "Camera";
1436                 break;
1437         case OB_CURVE:
1438                 str = "Curve";
1439                 break;
1440         case OB_EMPTY:
1441                 str = "Empty";
1442                 break;
1443         case OB_FONT:
1444                 str = "Text";
1445                 break;
1446         case OB_LAMP:
1447                 str = "Lamp";
1448                 break;
1449         case OB_LATTICE:
1450                 str = "Lattice";
1451                 break;
1452         case OB_MBALL:
1453                 str = "MBall";
1454                 break;
1455         case OB_MESH:
1456                 str = "Mesh";
1457                 break;
1458         case OB_SURF:
1459                 str = "Surf";
1460                 break;
1461         case OB_WAVE:
1462                 str = "Wave";
1463                 break;
1464         default:
1465                 str = "unknown";
1466                 break;
1467         }
1468
1469         return PyString_FromString( str );
1470 }
1471
1472 static PyObject *Object_getBoundBox( BPy_Object * self, PyObject *args )
1473 {
1474         float *vec = NULL;
1475         PyObject *vector, *bbox;
1476         int worldspace = 1;
1477         
1478         if( !PyArg_ParseTuple( args, "|i", &worldspace ) )
1479                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1480                                         "expected an int or nothing" );
1481
1482         if( !self->object->data )
1483                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1484                                 "This object isn't linked to any object data (mesh, curve, etc) yet" );
1485
1486         if( !self->object->bb ) {       /* if no ob bbox, we look in obdata */
1487                 Mesh *me;
1488                 Curve *curve;
1489                 switch ( self->object->type ) {
1490                 case OB_MESH:
1491                         me = self->object->data;
1492                         vec = (float*) mesh_get_bb(self->object)->vec;
1493                         break;
1494                 case OB_CURVE:
1495                 case OB_FONT:
1496                 case OB_SURF:
1497                         curve = self->object->data;
1498                         if( !curve->bb )
1499                                 tex_space_curve( curve );
1500                         vec = ( float * ) curve->bb->vec;
1501                         break;
1502                 default:
1503                         Py_RETURN_NONE;
1504                 }
1505         } else {                /* the ob bbox exists */
1506                 vec = ( float * ) self->object->bb->vec;
1507         }
1508
1509
1510         {       /* transform our obdata bbox by the obmat.
1511                    the obmat is 4x4 homogeneous coords matrix.
1512                    each bbox coord is xyz, so we make it homogenous
1513                    by padding it with w=1.0 and doing the matrix mult.
1514                    afterwards we divide by w to get back to xyz.
1515                  */
1516                 /* printmatrix4( "obmat", self->object->obmat); */
1517
1518                 float tmpvec[4];        /* tmp vector for homogenous coords math */
1519                 int i;
1520                 float *from;
1521
1522                 bbox = PyList_New( 8 );
1523                 if( !bbox )
1524                         return EXPP_ReturnPyObjError
1525                                 ( PyExc_MemoryError,
1526                                   "couldn't create pylist" );
1527                 for( i = 0, from = vec; i < 8; i++, from += 3 ) {
1528                         memcpy( tmpvec, from, 3 * sizeof( float ) );
1529                         tmpvec[3] = 1.0f;       /* set w coord */
1530                         
1531                         if (worldspace) {
1532                                 Mat4MulVec4fl( self->object->obmat, tmpvec );
1533                                 /* divide x,y,z by w */
1534                                 tmpvec[0] /= tmpvec[3];
1535                                 tmpvec[1] /= tmpvec[3];
1536                                 tmpvec[2] /= tmpvec[3];
1537
1538 #if 0
1539                                 {       /* debug print stuff */
1540                                         int i;
1541         
1542                                         printf( "\nobj bbox transformed\n" );
1543                                         for( i = 0; i < 4; ++i )
1544                                                 printf( "%f ", tmpvec[i] );
1545         
1546                                         printf( "\n" );
1547                                 }
1548 #endif
1549                         }
1550                         /* because our bounding box is calculated and
1551                            does not have its own memory,
1552                            we must create vectors that allocate space */
1553
1554                         vector = newVectorObject( NULL, 3, Py_NEW);
1555                         memcpy( ( ( VectorObject * ) vector )->vec,
1556                                 tmpvec, 3 * sizeof( float ) );
1557                         PyList_SET_ITEM( bbox, i, vector );
1558                 }
1559         }
1560
1561         return bbox;
1562 }
1563
1564 static PyObject *Object_getBoundBox_noargs( BPy_Object * self )
1565 {
1566         return Object_getBoundBox(self, PyTuple_New(0));
1567 }
1568
1569 static PyObject *Object_makeDisplayList( BPy_Object * self )
1570 {
1571         Object *ob = self->object;
1572
1573         if( ob->type == OB_FONT ) {
1574                 Curve *cu = ob->data;
1575                 freedisplist( &cu->disp );
1576                 text_to_curve( ob, 0 );
1577         }
1578
1579         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1580
1581         Py_RETURN_NONE;
1582 }
1583
1584 static PyObject *Object_link( BPy_Object * self, PyObject * args )
1585 {
1586         PyObject *py_data;
1587         ID *id;
1588         ID *oldid;
1589         int obj_id;
1590         void *data = NULL;
1591         int ok;
1592
1593         if( !PyArg_ParseTuple( args, "O", &py_data ) )
1594                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1595                                 "expected an object as argument" );
1596
1597         if( BPy_Armature_Check( py_data ) )
1598                 data = ( void * ) PyArmature_AsArmature((BPy_Armature*)py_data);
1599         else if( BPy_Camera_Check( py_data ) )
1600                 data = ( void * ) Camera_FromPyObject( py_data );
1601         else if( BPy_Lamp_Check( py_data ) )
1602                 data = ( void * ) Lamp_FromPyObject( py_data );
1603         else if( BPy_Curve_Check( py_data ) )
1604                 data = ( void * ) Curve_FromPyObject( py_data );
1605         else if( BPy_NMesh_Check( py_data ) ) {
1606                 data = ( void * ) NMesh_FromPyObject( py_data, self->object );
1607                 if( !data )             /* NULL means there is already an error */
1608                         return NULL;
1609         } else if( BPy_Mesh_Check( py_data ) )
1610                 data = ( void * ) Mesh_FromPyObject( py_data, self->object );
1611         else if( BPy_Lattice_Check( py_data ) )
1612                 data = ( void * ) Lattice_FromPyObject( py_data );
1613         else if( BPy_Metaball_Check( py_data ) )
1614                 data = ( void * ) Metaball_FromPyObject( py_data );
1615         else if( BPy_Text3d_Check( py_data ) )
1616                 data = ( void * ) Text3d_FromPyObject( py_data );
1617
1618         /* have we set data to something good? */
1619         if( !data )
1620                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1621                                 "link argument type is not supported " );
1622
1623         oldid = ( ID * ) self->object->data;
1624         id = ( ID * ) data;
1625         obj_id = MAKE_ID2( id->name[0], id->name[1] );
1626
1627         /* if the object object has not been linked to real data before, we
1628          * can now let it assume its real type */
1629         if( self->realtype != OB_EMPTY ) {
1630                 self->object->type = self->realtype;
1631                 self->realtype = OB_EMPTY;
1632         }
1633
1634         ok = 1;
1635         switch ( obj_id ) {
1636         case ID_AR:
1637                 if( self->object->type != OB_ARMATURE ) {
1638                         ok = 0;
1639                 }
1640                 break;
1641         case ID_CA:
1642                 if( self->object->type != OB_CAMERA ) {
1643                         ok = 0;
1644                 }
1645                 break;
1646         case ID_LA:
1647                 if( self->object->type != OB_LAMP ) {
1648                         ok = 0;
1649                 }
1650                 break;
1651         case ID_ME:
1652                 if( self->object->type != OB_MESH ) {
1653                         ok = 0;
1654                 }
1655                 break;
1656         case ID_CU:
1657                 if( self->object->type != OB_CURVE && self->object->type != OB_FONT ) {
1658                         ok = 0;
1659                 }
1660                 break;
1661         case ID_LT:
1662                 if( self->object->type != OB_LATTICE ) {
1663                         ok = 0;
1664                 }
1665                 break;
1666         case ID_MB:
1667                 if( self->object->type != OB_MBALL ) {
1668                         ok = 0;
1669                 }
1670                 break;
1671         default:
1672                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1673                                 "Linking this object type is not supported" );
1674         }
1675
1676         if( !ok )
1677                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1678                                 "The 'link' object is incompatible with the base object" );
1679         self->object->data = data;
1680
1681         /* creates the curve for the text object */
1682         if (self->object->type == OB_FONT) {
1683                 text_to_curve(self->object, 0);
1684         } else if (self->object->type == OB_ARMATURE) {
1685                 armature_rebuild_pose(self->object, (bArmature *)data);
1686         }
1687         id_us_plus( id );
1688         if( oldid ) {
1689                 if( oldid->us > 0 ) {
1690                         oldid->us--;
1691                 } else {
1692                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1693                                         "old object reference count below 0" );
1694                 }
1695         }
1696
1697         /* make sure data and object materials are consistent */
1698         test_object_materials( id );
1699
1700         Py_RETURN_NONE;
1701 }
1702
1703 static PyObject *Object_makeParentVertex( BPy_Object * self, PyObject * args )
1704 {
1705         PyObject *list;
1706         PyObject *vlist;
1707         PyObject *py_child;
1708         PyObject *ret_val;
1709         Object *parent;
1710         int noninverse = 0;
1711         int fast = 0;
1712         int partype;
1713         int v1, v2=0, v3=0;
1714         int i;
1715
1716         /* Check if the arguments passed to makeParent are valid. */
1717         if( !PyArg_ParseTuple( args, "OO|ii", &list, &vlist, &noninverse, &fast ) )
1718                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1719                                 "expected a list of objects, a tuple of integers and one or two integers as arguments" );
1720
1721         if( !PySequence_Check( list ) )
1722                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1723                                                 "expected a list of objects" );
1724
1725         if (!PyTuple_Check( vlist ))
1726                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1727                                                 "expected a tuple of integers" );
1728
1729         switch( PyTuple_Size( vlist ) ) {
1730         case 1:
1731                 if( !PyArg_ParseTuple( vlist, "i", &v1 ) )
1732                         return EXPP_ReturnPyObjError( PyExc_TypeError,
1733                                 "expected a tuple of 1 or 3 integers" );
1734
1735                 if ( v1 < 0 )
1736                         return EXPP_ReturnPyObjError( PyExc_ValueError,
1737                                 "indices must be strictly positive" );
1738
1739                 partype = PARVERT1;
1740                 break;
1741         case 3:
1742                 if( !PyArg_ParseTuple( vlist, "iii", &v1, &v2, &v3 ) )
1743                         return EXPP_ReturnPyObjError( PyExc_TypeError,
1744                                         "expected a tuple of 1 or 3 integers" );
1745
1746                 if ( v1 < 0 || v2 < 0 || v3 < 0)
1747                         return EXPP_ReturnPyObjError( PyExc_ValueError,
1748                                                 "indices must be strictly positive" );
1749                 partype = PARVERT3;
1750                 break;
1751         default:
1752                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1753                                 "expected a tuple of 1 or 3 integers" );
1754         }
1755
1756         parent = ( Object * ) self->object;
1757
1758         if (!ELEM3(parent->type, OB_MESH, OB_CURVE, OB_SURF))
1759                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1760                                 "Parent Vertex only applies to curve, mesh or surface objects" );
1761
1762         if (parent->id.us == 0)
1763                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
1764                         "object must be linked to a scene before it can become a parent");
1765
1766         /* Check if the PyObject passed in list is a Blender object. */
1767         for( i = 0; i < PySequence_Length( list ); i++ ) {
1768                 py_child = PySequence_GetItem( list, i );
1769
1770                 ret_val = internal_makeParent(parent, py_child, partype, noninverse, fast, v1, v2, v3, NULL);
1771                 Py_DECREF (py_child);
1772
1773                 if (ret_val)
1774                         Py_DECREF(ret_val);
1775                 else {
1776                         if (!fast)      /* need to sort when interrupting in the middle of the list */
1777                                 DAG_scene_sort( G.scene );
1778                         return NULL; /* error has been set already */
1779                 }
1780         }
1781
1782         if (!fast) /* otherwise, only sort at the end */
1783                 DAG_scene_sort( G.scene );
1784
1785         Py_RETURN_NONE;
1786 }
1787
1788 static PyObject *Object_makeParentDeform( BPy_Object * self, PyObject * args )
1789 {
1790         PyObject *list;
1791         PyObject *py_child;
1792         PyObject *ret_val;
1793         Object *parent;
1794         int noninverse = 0;
1795         int fast = 0;
1796         int i;
1797
1798         /* Check if the arguments passed to makeParent are valid. */
1799         if( !PyArg_ParseTuple( args, "O|ii", &list, &noninverse, &fast ) )
1800                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1801                                 "expected a list of objects and one or two integers as arguments" );
1802
1803         if( !PySequence_Check( list ) )
1804                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1805                                 "expected a list of objects" );
1806
1807         parent = ( Object * ) self->object;
1808
1809         if (parent->type != OB_CURVE && parent->type != OB_ARMATURE)
1810                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1811                                 "Parent Deform only applies to curve or armature objects" );
1812
1813         if (parent->id.us == 0)
1814                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
1815                         "object must be linked to a scene before it can become a parent");
1816
1817         /* Check if the PyObject passed in list is a Blender object. */
1818         for( i = 0; i < PySequence_Length( list ); i++ ) {
1819                 py_child = PySequence_GetItem( list, i );
1820
1821                 ret_val = internal_makeParent(parent, py_child, PARSKEL, noninverse, fast, 0, 0, 0, NULL);
1822                 Py_DECREF (py_child);
1823
1824                 if (ret_val)
1825                         Py_DECREF(ret_val);
1826                 else {
1827                         if (!fast)      /* need to sort when interupting in the middle of the list */
1828                                 DAG_scene_sort( G.scene );
1829                         return NULL; /* error has been set already */
1830                 }
1831         }
1832
1833         if (!fast) /* otherwise, only sort at the end */
1834                 DAG_scene_sort( G.scene );
1835
1836         Py_RETURN_NONE;
1837 }
1838
1839
1840 static PyObject *Object_makeParentBone( BPy_Object * self, PyObject * args )
1841 {
1842         char *bonename;
1843         PyObject *list;
1844         PyObject *py_child;
1845         PyObject *ret_val;
1846         Object *parent;
1847         int noninverse = 0;
1848         int fast = 0;
1849         int i;
1850         
1851         /* Check if the arguments passed to makeParent are valid. */
1852         if( !PyArg_ParseTuple( args, "Os|ii", &list, &bonename, &noninverse, &fast ) )
1853                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1854                                 "expected a list of objects, bonename and optionally two integers as arguments" );
1855         
1856         parent = ( Object * ) self->object;
1857         
1858         if (parent->type != OB_ARMATURE)
1859                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1860                                 "Parent Bone only applies to armature objects" );
1861
1862         if (parent->id.us == 0)
1863                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
1864                         "object must be linked to a scene before it can become a parent");
1865         
1866         if (!parent->data)
1867                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
1868                         "object must be linked to armature data");
1869         
1870         if (!get_named_bone(parent->data, bonename))
1871                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1872                                 "Parent Bone Name is not in the armature" );
1873         
1874         /* Check if the PyObject passed in list is a Blender object. */
1875         for( i = 0; i < PySequence_Length( list ); i++ ) {
1876                 py_child = PySequence_GetItem( list, i );
1877
1878                 ret_val = internal_makeParent(parent, py_child, PARBONE, noninverse, fast, 0, 0, 0, bonename);
1879                 Py_DECREF (py_child);
1880
1881                 if (ret_val)
1882                         Py_DECREF(ret_val);
1883                 else {
1884                         if (!fast)      /* need to sort when interupting in the middle of the list */
1885                                 DAG_scene_sort( G.scene );
1886                         return NULL; /* error has been set already */
1887                 }
1888         }
1889
1890         if (!fast) /* otherwise, only sort at the end */
1891                 DAG_scene_sort( G.scene );
1892
1893         Py_RETURN_NONE;
1894 }
1895
1896
1897 static PyObject *Object_makeParent( BPy_Object * self, PyObject * args )
1898 {
1899         PyObject *list;
1900         PyObject *py_child;
1901         PyObject *ret_val;
1902         Object *parent;
1903         int noninverse = 0;
1904         int fast = 0;
1905         int i;
1906
1907         /* Check if the arguments passed to makeParent are valid. */
1908         if( !PyArg_ParseTuple( args, "O|ii", &list, &noninverse, &fast ) )
1909                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1910                                         "expected a list of objects and one or two integers as arguments" );
1911
1912         if( !PySequence_Check( list ) )
1913                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1914                                 "expected a list of objects" );
1915
1916         parent = ( Object * ) self->object;
1917
1918         if (parent->id.us == 0)
1919                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
1920                         "object must be linked to a scene before it can become a parent");
1921
1922         /* Check if the PyObject passed in list is a Blender object. */
1923         for( i = 0; i < PySequence_Length( list ); i++ ) {
1924                 py_child = PySequence_GetItem( list, i );
1925
1926                 ret_val = internal_makeParent(parent, py_child, PAROBJECT, noninverse, fast, 0, 0, 0, NULL);
1927                 Py_DECREF (py_child);
1928
1929                 if (ret_val)
1930                         Py_DECREF(ret_val);
1931                 else {
1932                         if (!fast)      /* need to sort when interupting in the middle of the list */
1933                                 DAG_scene_sort( G.scene );
1934                         return NULL; /* error has been set already */
1935                 }
1936         }
1937
1938         if (!fast) /* otherwise, only sort at the end */
1939                 DAG_scene_sort( G.scene );
1940
1941         Py_RETURN_NONE;
1942 }
1943
1944 static PyObject *Object_join( BPy_Object * self, PyObject * args )
1945 {
1946         PyObject *list;
1947         PyObject *py_child;
1948         Object *parent;
1949         Object *child;
1950         Scene *temp_scene;
1951         Scene *orig_scene;
1952         Base *temp_base;
1953         short type;
1954         int i, ok=0, ret_value=0, list_length=0;
1955
1956         /* joining in background causes segfaults */
1957         if( G.background == 1 )
1958                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1959                                         "cannot join objects in background mode" );
1960
1961         /* Check if the arguments passed to makeParent are valid. */
1962         if( !PyArg_ParseTuple( args, "O", &list ) )
1963                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1964                                 "expected a list of objects" );
1965         
1966         if( !PySequence_Check( list ) )
1967                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1968                                         "expected a list of objects" );
1969         
1970         list_length = PySequence_Length( list ); /* if there are no objects to join then exit silently */
1971         
1972         if( !list_length ) {
1973                 Py_RETURN_NONE;
1974         }
1975         
1976         parent = ( Object * ) self->object;
1977         type = parent->type;
1978         
1979         /* Only these object types are sypported */
1980         if( type!=OB_MESH && type!=OB_CURVE && type!=OB_SURF && type!=OB_ARMATURE )
1981                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1982                                                 "Base object is not a type Blender can join" );
1983         
1984         if( !object_in_scene( parent, G.scene ) )
1985                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1986                                 "object must be in the current scene" );
1987
1988         /* exit editmode so join can be done */
1989         if( G.obedit )
1990                 exit_editmode( EM_FREEDATA );
1991         
1992         temp_scene = add_scene( "Scene" ); /* make the new scene */
1993         temp_scene->lay= 1; /* first layer on */
1994         
1995         /* TODO: use EXPP_check_sequence_consistency here */
1996
1997         /* Check if the PyObject passed in list is a Blender object. */
1998         for( i = 0; i < list_length; i++ ) {
1999                 py_child = PySequence_GetItem( list, i );
2000                 if( !BPy_Object_Check( py_child ) ) {
2001                         /* Cleanup */
2002                         free_libblock( &G.main->scene, temp_scene );
2003                         Py_DECREF( py_child );
2004                         return EXPP_ReturnPyObjError( PyExc_TypeError,
2005                                         "expected a list of objects, one or more of the list items is not a Blender Object." );
2006                 } else {
2007                         /* List item is an object, is it the same type? */
2008                         child = ( Object * ) Object_FromPyObject( py_child );
2009                         Py_DECREF( py_child );
2010                         if( parent->type == child->type ) {
2011                                 if( !object_in_scene( child, G.scene ) ) {
2012                                         free_libblock( &G.main->scene, temp_scene );
2013                                         return EXPP_ReturnPyObjError( PyExc_AttributeError,
2014                                                         "object must be in the current scene" );
2015                                 }
2016
2017                                 ok =1;
2018                                 /* Add a new base, then link the base to the temp_scene */
2019                                 temp_base = MEM_callocN( sizeof( Base ), "pynewbase" );
2020                                 /* we know these types are the same, link to the temp scene
2021                                  * for joining */
2022                                 temp_base->object = child;      /* link object to the new base */
2023                                 temp_base->flag |= SELECT;
2024                                 temp_base->lay = 1; /*1 layer on */
2025                                 
2026                                 BLI_addhead( &temp_scene->base, temp_base );    /* finally, link new base to scene */
2027                                 child->id.us += 1; /*Would usually increase user count but in this case it's ok not to */
2028                                 
2029                                 /*DAG_object_flush_update(temp_scene, temp_base->object, OB_RECALC_DATA);*/
2030                         }
2031                 }
2032         }
2033         
2034         orig_scene = G.scene; /* backup our scene */
2035         
2036         /* Add the main object into the temp_scene */
2037         temp_base = MEM_callocN( sizeof( Base ), "pynewbase" );
2038         temp_base->object = parent;     /* link object to the new base */
2039         temp_base->flag |= SELECT;
2040         temp_base->lay = 1; /*1 layer on */
2041         BLI_addhead( &temp_scene->base, temp_base );    /* finally, link new base to scene */
2042         parent->id.us += 1;
2043         
2044         /* all objects in the scene, set it active and the active object */
2045         set_scene( temp_scene );
2046         set_active_base( temp_base );
2047         
2048         /* Do the joining now we know everythings OK. */
2049         if(type == OB_MESH)
2050                 ret_value = join_mesh();
2051         else if(type == OB_CURVE)
2052                 ret_value = join_curve(OB_CURVE);
2053         else if(type == OB_SURF)
2054                 ret_value = join_curve(OB_SURF);
2055         else if(type == OB_ARMATURE)
2056                 ret_value = join_armature();
2057         
2058         /* May use this for correcting object user counts later on */
2059         /*
2060         if (!ret_value) {
2061                 temp_base = temp_scene->base.first;
2062                 while( base ) {
2063                         object = base->object;
2064                         object->id.us +=1
2065                         base = base->next;
2066                 }
2067         }*/
2068
2069         /* remove old scene */
2070         set_scene( orig_scene );
2071         free_libblock( &G.main->scene, temp_scene );
2072
2073         /* no objects were of the correct type, return None */
2074         if (!ok) {
2075                 Py_RETURN_NONE;
2076         }
2077
2078         /* If the join failed then raise an error */
2079         if (!ret_value)
2080                 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
2081 "Blender failed to join the objects, this is not a script error.\n\
2082 Please add exception handling to your script with a RuntimeError exception\n\
2083 letting the user know that their data could not be joined." ) );
2084
2085         Py_RETURN_NONE;
2086 }
2087
2088 static PyObject *internal_makeParent(Object *parent, PyObject *py_child,
2089                 int partype,                /* parenting type */
2090                 int noninverse, int fast,   /* parenting arguments */
2091                 int v1, int v2, int v3,     /* for vertex parent */
2092                 char *bonename)             /* for bone parents - assume the name is already checked to be a valid bone name*/
2093 {
2094         Object *child = NULL;
2095
2096         if( BPy_Object_Check( py_child ) )
2097                 child = ( Object * ) Object_FromPyObject( py_child );
2098
2099         if( child == NULL )
2100                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2101                                         "Object Type expected" );
2102
2103         if( test_parent_loop( parent, child ) )
2104                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2105                                 "parenting loop detected - parenting failed" );
2106
2107         if (partype == PARSKEL && child->type != OB_MESH)
2108                 child->partype = PAROBJECT;
2109         else
2110                 child->partype = (short)partype;
2111
2112         if (partype == PARVERT3) {
2113                 child->par1 = v1;
2114                 child->par2 = v2;
2115                 child->par3 = v3;
2116         }
2117         else if (partype == PARVERT1) {
2118                 child->par1 = v1;
2119         } else if (partype == PARBONE) {
2120                 strcpy( child->parsubstr, bonename );
2121         }
2122         
2123         
2124
2125         child->parent = parent;
2126         /* py_obj_child = (BPy_Object *) py_child; */
2127         if( noninverse == 1 ) {
2128                 Mat4One(child->parentinv);
2129                 /* Parent inverse = unity */
2130                 child->loc[0] = 0.0;
2131                 child->loc[1] = 0.0;
2132                 child->loc[2] = 0.0;
2133         } else {
2134                 what_does_parent( child );
2135                 Mat4Invert( child->parentinv, workob.obmat );
2136                 clear_workob();
2137         }
2138
2139         if( !fast )
2140                 child->recalc |= OB_RECALC_OB;
2141
2142         Py_RETURN_NONE;
2143 }
2144
2145 static PyObject *Object_materialUsage( void )
2146 {
2147         return EXPP_ReturnPyObjError( PyExc_NotImplementedError,
2148                         "materialUsage: not yet implemented" );
2149 }
2150
2151 static PyObject *Object_setDeltaLocation( BPy_Object * self, PyObject * args )
2152 {
2153         float dloc1;
2154         float dloc2;
2155         float dloc3;
2156         int status;
2157
2158         if( PyObject_Length( args ) == 3 )
2159                 status = PyArg_ParseTuple( args, "fff", &dloc1, &dloc2,
2160                                            &dloc3 );
2161         else
2162                 status = PyArg_ParseTuple( args, "(fff)", &dloc1, &dloc2,
2163                                            &dloc3 );
2164
2165         if( !status )
2166                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2167                                 "expected sequence argument of 3 floats" );
2168
2169         self->object->dloc[0] = dloc1;
2170         self->object->dloc[1] = dloc2;
2171         self->object->dloc[2] = dloc3;
2172
2173         /* since we have messed with object, we need to flag for DAG recalc */
2174         self->object->recalc |= OB_RECALC_OB;  
2175
2176         Py_RETURN_NONE;
2177 }
2178
2179 #define DTX_MASK ( OB_AXIS | OB_TEXSPACE | OB_DRAWNAME | \
2180                 OB_DRAWIMAGE | OB_DRAWWIRE | OB_DRAWXRAY | OB_DRAWTRANSP )
2181
2182 static PyObject *Object_getDrawMode( BPy_Object * self )
2183 {
2184         return PyInt_FromLong( (long)(self->object->dtx & DTX_MASK) );
2185 }
2186
2187 static int Object_setDrawMode( BPy_Object * self, PyObject * args )
2188 {
2189         PyObject* integer = PyNumber_Int( args );
2190         int value;
2191
2192         if( !integer )
2193                 return EXPP_ReturnIntError( PyExc_TypeError,
2194                                 "expected integer argument" );
2195
2196         value = ( int )PyInt_AS_LONG( integer );
2197         Py_DECREF( integer );
2198         if( value & ~DTX_MASK )
2199                 return EXPP_ReturnIntError( PyExc_ValueError,
2200                                 "undefined bit(s) set in bitfield" );
2201
2202         self->object->dtx = value;
2203         self->object->recalc |= OB_RECALC_OB;  
2204
2205         return 0;
2206 }
2207
2208 static PyObject *Object_getDrawType( BPy_Object * self )
2209 {
2210         return PyInt_FromLong( (long)self->object->dt );
2211 }
2212
2213 static int Object_setDrawType( BPy_Object * self, PyObject * value )
2214 {
2215         /* since we mess with object, we need to flag for DAG recalc */
2216         self->object->recalc |= OB_RECALC_OB;  
2217
2218         return EXPP_setIValueRange( value, &self->object->dt,
2219                         OB_BOUNDBOX, OB_TEXTURE, 'b' );
2220 }
2221
2222 static int Object_setEuler( BPy_Object * self, PyObject * args )
2223 {
2224         float rot1, rot2, rot3;
2225         int status = 0;         /* failure */
2226
2227         if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
2228                 args = PyTuple_GET_ITEM( args, 0 );
2229
2230         if( EulerObject_Check( args ) ) {
2231                 rot1 = ( ( EulerObject * ) args )->eul[0];
2232                 rot2 = ( ( EulerObject * ) args )->eul[1];
2233                 rot3 = ( ( EulerObject * ) args )->eul[2];
2234                 status = 1;
2235         } else if( PySequence_Check( args ) && PySequence_Size( args ) == 3 ) {
2236                 if( PyList_Check( args ) )
2237                         args = PySequence_Tuple( args );
2238                 else
2239                         Py_INCREF( args );
2240                 status = PyArg_ParseTuple( args, "fff", &rot1, &rot2, &rot3 );
2241                 Py_DECREF( args );
2242         }
2243
2244         if( !status )
2245                 return EXPP_ReturnIntError( PyExc_TypeError,
2246                                 "expected euler or sequence of 3 floats" );
2247
2248         self->object->rot[0] = rot1;
2249         self->object->rot[1] = rot2;
2250         self->object->rot[2] = rot3;
2251
2252         /* since we have messed with object, we need to flag for DAG recalc */
2253         self->object->recalc |= OB_RECALC_OB;  
2254
2255         return 0;
2256 }
2257
2258 static int Object_setMatrix( BPy_Object * self, MatrixObject * mat )
2259 #if 0
2260 {
2261         int x, y;
2262
2263         if( !MatrixObject_Check( mat ) )
2264                 return EXPP_ReturnIntError( PyExc_TypeError,
2265                                 "expected matrix object as argument" );
2266
2267         if( mat->rowSize == 4 && mat->colSize == 4 ) {
2268                 for( x = 0; x < 4; x++ ) {
2269                         for( y = 0; y < 4; y++ ) {
2270                                 self->object->obmat[x][y] = mat->matrix[x][y];
2271                         }
2272                 }
2273         } else if( mat->rowSize == 3 && mat->colSize == 3 ) {
2274                 for( x = 0; x < 3; x++ ) {
2275                         for( y = 0; y < 3; y++ ) {
2276                                 self->object->obmat[x][y] = mat->matrix[x][y];
2277                         }
2278                 }
2279                 /* if a 3x3 matrix, clear the fourth row/column */
2280                 for( x = 0; x < 3; x++ )
2281                         self->object->obmat[x][3] = self->object->obmat[3][x] = 0.0;
2282                 self->object->obmat[3][3] = 1.0;
2283         } else 
2284                 return EXPP_ReturnIntError( PyExc_ValueError,
2285                                 "expected 3x3 or 4x4 matrix" );
2286
2287         apply_obmat( self->object );
2288
2289         /* since we have messed with object, we need to flag for DAG recalc */
2290         self->object->recalc |= OB_RECALC_OB;  
2291
2292         return 0;
2293 }
2294 #endif
2295 {
2296         int x, y;
2297         float matrix[4][4]; /* for the result */
2298         float invmat[4][4]; /* for the result */
2299
2300         if( !MatrixObject_Check( mat ) )
2301                 return EXPP_ReturnIntError( PyExc_TypeError,
2302                                 "expected matrix object as argument" );
2303
2304         if( mat->rowSize == 4 && mat->colSize == 4 ) {
2305                 for( x = 0; x < 4; x++ ) {
2306                         for( y = 0; y < 4; y++ ) {
2307                                 matrix[x][y] = mat->matrix[x][y];
2308                         }
2309                 }
2310         } else if( mat->rowSize == 3 && mat->colSize == 3 ) {
2311                 for( x = 0; x < 3; x++ ) {
2312                         for( y = 0; y < 3; y++ ) {
2313                                 matrix[x][y] = mat->matrix[x][y];
2314                         }
2315                 }
2316                 /* if a 3x3 matrix, clear the fourth row/column */
2317                 for( x = 0; x < 3; x++ )
2318                         matrix[x][3] = matrix[3][x] = 0.0;
2319                 matrix[3][3] = 1.0;
2320         } else 
2321                 return EXPP_ReturnIntError( PyExc_ValueError,
2322                                 "expected 3x3 or 4x4 matrix" );
2323
2324         /* localspace matrix is truly relative to the parent, but parameters
2325          * stored in object are relative to parentinv matrix.  Undo the parent
2326          * inverse part before updating obmat and calling apply_obmat() */
2327         if( self->object->parent ) {
2328                 Mat4Invert( invmat, self->object->parentinv );
2329                 Mat4MulMat4( self->object->obmat, matrix, invmat );
2330         } else
2331                 Mat4CpyMat4( self->object->obmat, matrix );
2332
2333         apply_obmat( self->object );
2334
2335         /* since we have messed with object, we need to flag for DAG recalc */
2336         self->object->recalc |= OB_RECALC_OB;  
2337
2338         return 0;
2339 }
2340
2341
2342 /*
2343  * Object_insertIpoKey()
2344  *  inserts Object IPO key for LOC, ROT, SIZE, LOCROT, LOCROTSIZE, or LAYER
2345  *  Note it also inserts actions! 
2346  */
2347
2348 static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args )
2349 {
2350         Object *ob= self->object;
2351         int key = 0;
2352         char *actname= NULL;
2353
2354         if( !PyArg_ParseTuple( args, "i", &key ) )
2355                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2356                                 "expected int argument" );
2357
2358         if(ob->ipoflag & OB_ACTION_OB)
2359                 actname= "Object";
2360         
2361         if (key == IPOKEY_LOC || key == IPOKEY_LOCROT || key == IPOKEY_LOCROTSIZE){
2362                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_X, 0);
2363                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_Y, 0);
2364                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_Z, 0);      
2365         }
2366         if (key == IPOKEY_ROT || key == IPOKEY_LOCROT || key == IPOKEY_LOCROTSIZE){
2367                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_X, 0);
2368                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_Y, 0);
2369                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_Z, 0);      
2370         }
2371         if (key == IPOKEY_SIZE || key == IPOKEY_LOCROTSIZE ){
2372                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_X, 0);
2373                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_Y, 0);
2374                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_Z, 0);      
2375         }
2376         if (key == IPOKEY_LAYER ){
2377                 insertkey((ID *)ob, ID_OB, actname, NULL,OB_LAY, 0);
2378         }
2379
2380         if (key == IPOKEY_PI_STRENGTH ){
2381                 insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_FSTR, 0);   
2382         } else if (key == IPOKEY_PI_FALLOFF ){
2383                 insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_FFALL, 0);   
2384         } else if (key == IPOKEY_PI_SURFACEDAMP ){
2385                 insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_SDAMP, 0);   
2386         } else if (key == IPOKEY_PI_RANDOMDAMP ){
2387                 insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_RDAMP, 0);   
2388         } else if (key == IPOKEY_PI_PERM ){
2389                 insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_PERM, 0);   
2390         }
2391
2392         allspace(REMAKEIPO, 0);
2393         EXPP_allqueue(REDRAWIPO, 0);
2394         EXPP_allqueue(REDRAWVIEW3D, 0);
2395         EXPP_allqueue(REDRAWACTION, 0);
2396         EXPP_allqueue(REDRAWNLA, 0);
2397
2398         Py_RETURN_NONE;
2399 }
2400
2401 /*
2402  * Object_insertPoseKey()
2403  * inserts a Action Pose key from a given pose (sourceaction, frame) to the
2404  * active action to a given framenum
2405  */
2406
2407 static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args )
2408 {
2409         Object *ob= self->object;
2410         BPy_Action *sourceact;
2411         char *chanName;
2412         int actframe;
2413
2414
2415         /* for doing the time trick, similar to editaction bake_action_with_client() */
2416         int oldframe;
2417         int curframe;
2418
2419         if( !PyArg_ParseTuple( args, "O!sii", &Action_Type, &sourceact,
2420                                 &chanName, &actframe, &curframe ) )
2421                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2422                                 "expects an action to copy poses from, a string for chan/bone name, an int argument for frame to extract from the action and finally another int for the frame where to put the new key in the active object.action" );
2423
2424         extract_pose_from_action(ob->pose, sourceact->action, (float)actframe);
2425
2426         oldframe = G.scene->r.cfra;
2427         G.scene->r.cfra = curframe;
2428
2429         /* XXX: must check chanName actually exists, otherwise segfaults! */
2430         //achan = get_action_channel(sourceact->action, chanName);
2431
2432         insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X, 0);
2433         insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y, 0);
2434         insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z, 0);
2435         insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X, 0);
2436         insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y, 0);
2437         insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z, 0);
2438         insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W, 0);
2439         insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X, 0);
2440         insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y, 0);
2441         insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z, 0);
2442         
2443         G.scene->r.cfra = oldframe;
2444
2445         allspace(REMAKEIPO, 0);
2446         EXPP_allqueue(REDRAWIPO, 0);
2447         EXPP_allqueue(REDRAWVIEW3D, 0);
2448         EXPP_allqueue(REDRAWACTION, 0);
2449         EXPP_allqueue(REDRAWNLA, 0);
2450
2451         /* restore, but now with the new action in place */
2452         /*extract_pose_from_action(ob->pose, ob->action, G.scene->r.cfra);
2453         where_is_pose(ob);*/
2454         
2455         EXPP_allqueue(REDRAWACTION, 1);
2456
2457         Py_RETURN_NONE;
2458 }
2459
2460 static PyObject *Object_insertCurrentPoseKey( BPy_Object * self, PyObject * args )
2461 {
2462         Object *ob= self->object;
2463         char *chanName;
2464
2465         /* for doing the time trick, similar to editaction bake_action_with_client() */
2466         int oldframe;
2467         int curframe;
2468
2469         if( !PyArg_ParseTuple( args, "si", &chanName, &curframe ) )
2470                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2471                                 "expected chan/bone name, and a time (int) argument" );
2472
2473         oldframe = G.scene->r.cfra;
2474         G.scene->r.cfra = curframe;
2475
2476         /* XXX: must check chanName actually exists, otherwise segfaults! */
2477
2478         insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X, 0);
2479         insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y, 0);
2480         insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z, 0);
2481         insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X, 0);
2482         insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y, 0);
2483         insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z, 0);
2484         insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W, 0);
2485         insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X, 0);
2486         insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y, 0);
2487         insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z, 0);
2488
2489         G.scene->r.cfra = oldframe;
2490
2491         allspace(REMAKEIPO, 0);
2492         EXPP_allqueue(REDRAWIPO, 0);
2493         EXPP_allqueue(REDRAWVIEW3D, 0);
2494         EXPP_allqueue(REDRAWACTION, 0);
2495         EXPP_allqueue(REDRAWNLA, 0);
2496
2497         /* restore */
2498         extract_pose_from_action(ob->pose, ob->action, (float)G.scene->r.cfra);
2499         where_is_pose(ob);
2500
2501         EXPP_allqueue(REDRAWACTION, 1);
2502
2503         Py_RETURN_NONE;
2504 }  
2505
2506 static PyObject *Object_setConstraintInfluenceForBone( BPy_Object * self,
2507                 PyObject * args )
2508 {
2509         char *boneName, *constName;
2510         float influence;
2511         IpoCurve *icu;
2512
2513         if( !PyArg_ParseTuple( args, "ssf", &boneName, &constName, &influence ) )
2514                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2515                                 "expects bonename, constraintname, influenceval" );
2516         
2517         icu = verify_ipocurve((ID *)self->object, ID_CO, boneName, constName, NULL,
2518                         CO_ENFORCE);
2519         
2520         if (!icu)
2521                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2522                                 "cannot get a curve from this IPO, may be using libdata" );             
2523         
2524         insert_vert_icu(icu, (float)CFRA, influence, 0);
2525         self->object->recalc |= OB_RECALC_OB;  
2526
2527         Py_RETURN_NONE;
2528 }
2529
2530 static PyObject *Object_copyNLA( BPy_Object * self, PyObject * args ) {
2531         BPy_Object *bpy_fromob;
2532
2533         if( !PyArg_ParseTuple( args, "O", &bpy_fromob ) )
2534                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2535                                         "requires a Blender Object to copy NLA strips from." );
2536         copy_nlastrips(&self->object->nlastrips, &bpy_fromob->object->nlastrips);
2537         self->object->recalc |= OB_RECALC_OB;  
2538
2539         Py_RETURN_NONE;
2540 }
2541
2542 /*Now that  BPY has a Strip type, return the created strip.*/
2543 static PyObject *Object_convertActionToStrip( BPy_Object * self )
2544 {
2545         bActionStrip *strip = convert_action_to_strip( self->object );
2546         return ActionStrip_CreatePyObject( strip );
2547 }
2548
2549 static PyObject *Object_setLocation( BPy_Object * self, PyObject * args )
2550 {
2551         float loc1;
2552         float loc2;
2553         float loc3;
2554         int status;
2555
2556         if( PyObject_Length( args ) == 3 )
2557                 status = PyArg_ParseTuple( args, "fff", &loc1, &loc2, &loc3 );
2558         else
2559                 status = PyArg_ParseTuple( args, "(fff)", &loc1, &loc2,
2560                                            &loc3 );
2561
2562         if( !status )
2563                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2564                                 "expected list argument of 3 floats" );
2565
2566         self->object->loc[0] = loc1;
2567         self->object->loc[1] = loc2;
2568         self->object->loc[2] = loc3;
2569
2570         /* since we have messed with object, we need to flag for DAG recalc */
2571         self->object->recalc |= OB_RECALC_OB;  
2572         DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA);
2573
2574         Py_RETURN_NONE;
2575 }
2576
2577 static PyObject *Object_setMaterials( BPy_Object * self, PyObject * args )
2578 {
2579         PyObject *list;
2580         int len;
2581         int i;
2582         Material **matlist = NULL;
2583
2584         if (!self->object->data)
2585                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2586                                 "object must be linked to object data (e.g. to a mesh) first" );
2587
2588         if( !PyArg_ParseTuple( args, "O!", &PyList_Type, &list ) )
2589                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2590                                 "expected a list (of materials or None) as argument" );
2591
2592         len = PyList_Size(list);
2593
2594         /* Object_getMaterials can return '[]' (zero-length list), so that must
2595          * also be accepted by this method for
2596          * ob2.setMaterials(ob1.getMaterials()) to always work.
2597          * In other words, list can be '[]' and so len can be zero. */
2598         if (len > 0) {
2599                 if( len > MAXMAT )
2600                         return EXPP_ReturnPyObjError( PyExc_ValueError,
2601                                         "list must have from 1 up to 16 materials" );
2602
2603                 matlist = EXPP_newMaterialList_fromPyList( list );
2604                 if( !matlist )
2605                         return EXPP_ReturnPyObjError( PyExc_ValueError,
2606                                 "material list must be a list of valid materials!" );
2607         }
2608
2609         if( self->object->mat )
2610                 EXPP_releaseMaterialList( self->object->mat, self->object->totcol );
2611
2612         /* Increase the user count on all materials */
2613         for( i = 0; i < len; i++ ) {
2614                 if( matlist[i] )
2615                         id_us_plus( ( ID * ) matlist[i] );
2616         }
2617         self->object->mat = matlist;
2618         self->object->totcol = (char)len;
2619         self->object->actcol = (char)len;
2620
2621         switch ( self->object->type ) {
2622                 case OB_CURVE:  /* fall through */
2623                 case OB_FONT:   /* fall through */
2624                 case OB_MESH:   /* fall through */
2625                 case OB_MBALL:  /* fall through */
2626                 case OB_SURF:
2627                         EXPP_synchronizeMaterialLists( self->object );
2628                         break;
2629                 default:
2630                         break;
2631         }
2632
2633         /* since we have messed with object, we need to flag for DAG recalc */
2634         self->object->recalc |= OB_RECALC_OB;  
2635
2636         Py_RETURN_NONE;
2637 }
2638
2639 static PyObject *Object_setSize( BPy_Object * self, PyObject * args )
2640 {
2641         float sizex;
2642         float sizey;
2643         float sizez;
2644         int status;
2645
2646         if( PyObject_Length( args ) == 3 )
2647                 status = PyArg_ParseTuple( args, "fff", &sizex, &sizey,
2648                                            &sizez );
2649         else
2650                 status = PyArg_ParseTuple( args, "(fff)", &sizex, &sizey,
2651                                            &sizez );
2652
2653         if( !status )
2654                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2655                                 "expected list argument of 3 floats" );
2656
2657         self->object->size[0] = sizex;
2658         self->object->size[1] = sizey;
2659         self->object->size[2] = sizez;
2660
2661         /* since we have messed with object, we need to flag for DAG recalc */
2662         self->object->recalc |= OB_RECALC_OB;  
2663
2664         Py_RETURN_NONE;
2665 }
2666
2667 static PyObject *Object_makeTrack( BPy_Object * self, PyObject * args )
2668 {
2669         BPy_Object *tracked = NULL;
2670         Object *ob = self->object;
2671         int fast = 0;
2672
2673         if( !PyArg_ParseTuple( args, "O!|i", &Object_Type, &tracked, &fast ) )
2674                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2675                                 "expected an object and optionally also an int as arguments." );
2676
2677         ob->track = tracked->object;
2678
2679         if( !fast )
2680                 DAG_scene_sort( G.scene );
2681
2682         Py_RETURN_NONE;
2683 }
2684
2685 static PyObject *Object_shareFrom( BPy_Object * self, PyObject * args )
2686 {
2687         BPy_Object *object;
2688         ID *id;
2689         ID *oldid;
2690
2691         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &object ) )
2692                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2693                                               "expected an object argument" );
2694
2695         if( !object->object->data )
2696                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2697                                               "Object argument has no data linked yet or is an empty" );
2698         
2699         if( self->object->type != object->object->type &&
2700                 self->realtype != object->object->type)
2701                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2702                                               "objects are not of same data type" );
2703
2704         switch ( object->object->type ) {
2705         case OB_MESH:
2706         case OB_LAMP:
2707         case OB_CAMERA: /* we can probably add the other types, too */
2708         case OB_ARMATURE:
2709         case OB_CURVE:
2710         case OB_SURF:
2711         case OB_LATTICE:
2712                 
2713                 /* if this object had no data, we need to enable the realtype */
2714                 if (self->object->type == OB_EMPTY) {
2715                         self->object->type= self->realtype;
2716                         self->realtype = OB_EMPTY;
2717                 }
2718         
2719                 oldid = ( ID * ) self->object->data;
2720                 id = ( ID * ) object->object->data;
2721                 self->object->data = object->object->data;
2722
2723                 if( self->object->type == OB_MESH && id ) {
2724                         self->object->totcol = 0;
2725                         EXPP_synchronizeMaterialLists( self->object );
2726                 }
2727
2728                 id_us_plus( id );
2729                 if( oldid ) {
2730                         if( oldid->us > 0 ) {
2731                                 oldid->us--;
2732                         } else {
2733                                 return EXPP_ReturnPyObjError ( PyExc_RuntimeError,
2734                                            "old object reference count below 0" );
2735                         }
2736                 }
2737                 
2738                 Py_RETURN_NONE;
2739         default:
2740                 return EXPP_ReturnPyObjError( PyExc_ValueError,
2741                                 "object type not supported" );
2742         }
2743 }
2744
2745 static PyObject *Object_getAllProperties( BPy_Object * self )
2746 {
2747         PyObject *prop_list, *pyval;
2748         bProperty *prop = NULL;
2749
2750         prop_list = PyList_New( 0 );
2751
2752         prop = self->object->prop.first;
2753         while( prop ) {
2754                 pyval = Property_CreatePyObject( prop );
2755                 PyList_Append( prop_list, pyval );
2756                 Py_DECREF(pyval);
2757                 prop = prop->next;
2758         }
2759         return prop_list;
2760 }
2761
2762 static PyObject *Object_getProperty( BPy_Object * self, PyObject * args )
2763 {
2764         char *prop_name = NULL;
2765         bProperty *prop = NULL;
2766
2767         if( !PyArg_ParseTuple( args, "s", &prop_name ) )
2768                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2769                                 "expected a string" );
2770
2771         prop = get_property( self->object, prop_name );
2772         if( prop )
2773                 return Property_CreatePyObject( prop );
2774
2775         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2776                         "couldn't find the property" );
2777 }
2778
2779 static PyObject *Object_addProperty( BPy_Object * self, PyObject * args )
2780 {
2781         bProperty *prop = NULL;
2782         char *prop_name = NULL;
2783         PyObject *prop_data = Py_None;
2784         char *prop_type = NULL;
2785         short type = -1;
2786         BPy_Property *py_prop = NULL;
2787         int argslen = PyObject_Length( args );
2788
2789         if( argslen == 3 || argslen == 2 ) {
2790                 if( !PyArg_ParseTuple( args, "sO|s", &prop_name, &prop_data,
2791                                         &prop_type ) ) {
2792                         return EXPP_ReturnPyObjError( PyExc_TypeError,
2793                                         "expecting string, data, and optional string" );
2794                 }
2795         } else if( argslen == 1 ) {
2796                 if( !PyArg_ParseTuple( args, "O!", &property_Type, &py_prop ) )
2797                         return EXPP_ReturnPyObjError( PyExc_TypeError,
2798                                         "expecting a Property" );
2799
2800                 if( py_prop->property != NULL )
2801                         return EXPP_ReturnPyObjError( PyExc_ValueError,
2802                                         "Property is already added to an object" );
2803         } else {
2804                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2805                                 "expected 1,2 or 3 arguments" );
2806         }
2807
2808         /*parse property type*/
2809         if( !py_prop ) {
2810                 if( prop_type ) {
2811                         if( BLI_streq( prop_type, "BOOL" ) )
2812                                 type = PROP_BOOL;
2813                         else if( BLI_streq( prop_type, "INT" ) )
2814                                 type = PROP_INT;
2815                         else if( BLI_streq( prop_type, "FLOAT" ) )
2816                                 type = PROP_FLOAT;
2817                         else if( BLI_streq( prop_type, "TIME" ) )
2818                                 type = PROP_TIME;
2819                         else if( BLI_streq( prop_type, "STRING" ) )
2820                                 type = PROP_STRING;
2821                         else
2822                                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2823                                            "BOOL, INT, FLOAT, TIME or STRING expected" );
2824                 } else {
2825                         /*use the default*/
2826                         if( PyInt_Check( prop_data ) )
2827                                 type = PROP_INT;
2828                         else if( PyFloat_Check( prop_data ) )
2829                                 type = PROP_FLOAT;
2830                         else if( PyString_Check( prop_data ) )
2831                                 type = PROP_STRING;
2832                 }
2833         } else {
2834                 type = py_prop->type;
2835         }
2836
2837         /*initialize a new bProperty of the specified type*/
2838         prop = new_property( type );
2839
2840         /*parse data*/
2841         if( !py_prop ) {
2842                 BLI_strncpy( prop->name, prop_name, 32 );
2843                 if( PyInt_Check( prop_data ) ) {
2844                         *( ( int * ) &prop->data ) =
2845                                 ( int ) PyInt_AsLong( prop_data );
2846                 } else if( PyFloat_Check( prop_data ) ) {
2847                         *( ( float * ) &prop->data ) =
2848                                 ( float ) PyFloat_AsDouble( prop_data );
2849                 } else if( PyString_Check( prop_data ) ) {
2850                         BLI_strncpy( prop->poin,
2851                                      PyString_AsString( prop_data ),
2852                                      MAX_PROPSTRING );
2853                 }
2854         } else {
2855                 py_prop->property = prop;
2856
2857                 /* this should never be able to happen is we just assigned a valid
2858                  * proper to py_prop->property */
2859
2860                 if( !updateProperyData( py_prop ) ) {
2861                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2862                                                         "Could not update property data" );
2863                 }
2864         }
2865
2866         /*add to property listbase for the object*/
2867         BLI_addtail( &self->object->prop, prop );
2868
2869         Py_RETURN_NONE;
2870 }
2871
2872 static PyObject *Object_removeProperty( BPy_Object * self, PyObject * args )
2873 {
2874         char *prop_name = NULL;
2875         BPy_Property *py_prop = NULL;
2876         bProperty *prop = NULL;
2877
2878         /* we accept either a property stringname or actual object */
2879         if( PyTuple_Size( args ) == 1 ) {
2880                 PyObject *prop = PyTuple_GET_ITEM( args, 0 );
2881                 if( BPy_Property_Check( prop ) )
2882                         py_prop = (BPy_Property *)prop;
2883                 else
2884                         prop_name = PyString_AsString( prop );
2885         }
2886         if( !py_prop && !prop_name )
2887                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2888                                 "expected a Property or a string" );
2889
2890         /*remove the link, free the data, and update the py struct*/
2891         if( py_prop ) {
2892                 BLI_remlink( &self->object->prop, py_prop->property );
2893                 if( updatePyProperty( py_prop ) ) {
2894                         free_property( py_prop->property );
2895                         py_prop->property = NULL;
2896                 }
2897         } else {
2898                 prop = get_property( self->object, prop_name );
2899                 if( prop ) {
2900                         BLI_remlink( &self->object->prop, prop );
2901                         free_property( prop );
2902                 }
2903         }
2904         Py_RETURN_NONE;
2905 }
2906
2907 static PyObject *Object_removeAllProperties( BPy_Object * self )
2908 {
2909         free_properties( &self->object->prop );
2910         Py_RETURN_NONE;
2911 }
2912
2913 static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
2914                                              PyObject * args )
2915 {
2916         PyObject *dest;
2917         bProperty *prop = NULL;
2918         bProperty *propn = NULL;
2919
2920         if( !PyArg_ParseTuple( args, "O!", &Object_Type, &dest ) )
2921                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2922                                 "expected an Object" );
2923
2924         /*make a copy of all its properties*/
2925         prop = self->object->prop.first;
2926         while( prop ) {
2927                 propn = copy_property( prop );
2928                 BLI_addtail( &( ( BPy_Object * ) dest )->object->prop, propn );
2929                 prop = prop->next;
2930         }
2931
2932         Py_RETURN_NONE;
2933 }
2934
2935 static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args )
2936 {
2937         Object *obj = self->object;
2938         ScriptLink *slink = &obj->scriptlink;
2939         return EXPP_addScriptLink( slink, args, 0 );
2940 }
2941
2942 static PyObject *Object_clearScriptLinks( BPy_Object * self, PyObject * args )
2943 {
2944         Object *obj = self->object;
2945         ScriptLink *slink = &obj->scriptlink;
2946         return EXPP_clearScriptLinks( slink, args );
2947 }
2948
2949 static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * value )
2950 {
2951         Object *obj = self->object;
2952         ScriptLink *slink = &obj->scriptlink;
2953         return EXPP_getScriptLinks( slink, value, 0 );
2954 }
2955
2956 static PyObject *Object_getNLAflagBits ( BPy_Object * self ) 
2957 {
2958         if (self->object->nlaflag & OB_NLA_OVERRIDE)
2959                 Py_RETURN_TRUE;
2960         else
2961                 Py_RETURN_FALSE;
2962 }
2963
2964 static int Object_setNLAflagBits ( BPy_Object * self, PyObject * value ) 
2965 {
2966         int param;
2967
2968         param = PyObject_IsTrue( value );
2969         if( param == -1 )
2970                 return EXPP_ReturnIntError( PyExc_TypeError,
2971                                 "expected True/False or 0/1" );
2972
2973         if (param)
2974                 self->object->nlaflag |= OB_NLA_OVERRIDE;
2975         else 
2976                 self->object->nlaflag &= ~OB_NLA_OVERRIDE;
2977         
2978         self->object->recalc |= OB_RECALC_OB;  
2979
2980         return 0;
2981 }
2982
2983 static PyObject *Object_getDupliObjects( BPy_Object * self )
2984 {
2985         Object *ob= self->object;
2986         
2987         if(ob->transflag & OB_DUPLI) {
2988                 /* before make duplis, update particle for current frame */
2989                 /* TODO, build particles for particle dupli's */
2990                 if(ob->type!=OB_MBALL) {
2991                         PyObject *list;
2992                         DupliObject *dupob;
2993                         int index;
2994                         ListBase *duplilist = object_duplilist(G.scene, ob);
2995
2996                         list = PyList_New( BLI_countlist(duplilist) );
2997                         if( !list )
2998                                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2999                                                 "PyList_New() failed" );
3000
3001                         for(dupob= duplilist->first, index=0; dupob; dupob= dupob->next, index++) {
3002                                 PyObject *pair;
3003                                 pair = PyTuple_New( 2 );
3004                                 
3005                                 PyTuple_SET_ITEM( pair, 0, Object_CreatePyObject(dupob->ob) );
3006                                 PyTuple_SET_ITEM( pair, 1, newMatrixObject((float*)dupob->mat,4,4,Py_NEW) );
3007                                 PyList_SET_ITEM( list, index, pair);
3008                         }
3009                         free_object_duplilist(duplilist);
3010                         return list;
3011                 }
3012         }
3013         return PyList_New( 0 );
3014 }
3015
3016 static PyObject *Object_getDupliGroup( BPy_Object * self )
3017 {
3018         Object *ob= self->object;
3019
3020         if( ob->dup_group )
3021                 return Group_CreatePyObject( ob->dup_group );
3022
3023         Py_RETURN_NONE;
3024 }
3025
3026 static int Object_setDupliGroup( BPy_Object * self, PyObject * value )
3027 {
3028         return GenericLib_assignData(value, (void **) &self->object->dup_group, 0, 1, ID_GR, 0);
3029 }
3030
3031 static PyObject *Object_getEffects( BPy_Object * self )
3032 {
3033         return PyList_New( 0 );
3034 }
3035
3036 static PyObject *Object_getActionStrips( BPy_Object * self )
3037 {
3038         return ActionStrips_CreatePyObject( self->object );
3039 }
3040
3041 static PyObject *Object_getConstraints( BPy_Object * self )
3042 {
3043         return ObConstraintSeq_CreatePyObject( self->object );
3044 }
3045
3046 static PyObject *Object_getModifiers( BPy_Object * self )
3047 {
3048         return ModSeq_CreatePyObject( self->object, NULL );
3049 }
3050
3051 static int Object_setModifiers( BPy_Object * self, PyObject * value )
3052 {
3053         BPy_ModSeq *pymodseq;
3054         ModifierData *md;
3055         
3056         if (!BPy_ModSeq_Check(value))
3057                 return EXPP_ReturnIntError( PyExc_TypeError,
3058                                 "can only assign another objects modifiers" );
3059         
3060         pymodseq = ( BPy_ModSeq * ) value;
3061         
3062         if (self->object->type != pymodseq->object->type)
3063                 return EXPP_ReturnIntError( PyExc_TypeError,
3064                                 "can only assign modifiers between objects of the same type" );
3065         
3066         if (self->object == pymodseq->object)
3067                 return 0;
3068         
3069         object_free_modifiers(self->object);
3070         for (md=pymodseq->object->modifiers.first; md; md=md->next) {
3071                 if (md->type!=eModifierType_Hook) {
3072                         ModifierData *nmd = modifier_new(md->type);
3073                         modifier_copyData(md, nmd);
3074                         BLI_addtail(&self->object->modifiers, nmd);
3075                 }
3076         }
3077         
3078         DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA);
3079         return 0;
3080 }
3081
3082 static PyObject *Object_insertShapeKey(BPy_Object * self)
3083 {
3084         insert_shapekey(self->object);
3085         Py_RETURN_NONE;
3086 }
3087
3088 /* __copy__() */
3089 static  PyObject *Object_copy(BPy_Object * self)
3090 {
3091         /* copy_object never returns NULL */
3092         struct Object *object= copy_object( self->object );
3093         object->id.us= 0; /*is 1 by default, not sure why */
3094         
3095         /* Create a Python object from it. */
3096         return Object_CreatePyObject( object );
3097 }
3098
3099 /*****************************************************************************/
3100 /* Function:    Object_CreatePyObject                                    */
3101 /* Description: This function will create a new BlenObject from an existing  */
3102 /*              Object structure.                                        */
3103 /*****************************************************************************/
3104 PyObject *Object_CreatePyObject( struct Object * obj )
3105 {
3106         BPy_Object *blen_object;
3107
3108         if( !obj ) Py_RETURN_NONE;
3109         
3110         blen_object =
3111                 ( BPy_Object * ) PyObject_NEW( BPy_Object, &Object_Type );
3112
3113         if( blen_object == NULL ) {
3114                 return ( NULL );
3115         }
3116         blen_object->object = obj;
3117         blen_object->realtype = OB_EMPTY;
3118         obj->id.us++;
3119         return ( ( PyObject * ) blen_object );
3120 }
3121
3122 /*****************************************************************************/
3123 /* Function:    Object_FromPyObject                                      */
3124 /* Description: This function returns the Blender object from the given  */
3125 /*              PyObject.                                                */
3126 /*****************************************************************************/
3127 struct Object *Object_FromPyObject( PyObject * py_obj )
3128 {
3129         BPy_Object *blen_obj;
3130
3131         blen_obj = ( BPy_Object * ) py_obj;
3132         return ( blen_obj->object );
3133 }
3134
3135 /*****************************************************************************/
3136 /* Function:    Object_dealloc                                               */
3137 /* Description: This is a callback function for the BlenObject type. It is   */
3138 /*      the destructor function.                                             */
3139 /*****************************************************************************/
3140 static void Object_dealloc( BPy_Object * self )
3141 {
3142         if( self->realtype != OB_EMPTY ) 
3143                 free_libblock_us( &G.main->object, self->object );
3144         else 
3145                 self->object->id.us--;
3146
3147 #if 0   /* this will adjust the ID and if zero delete the object */
3148         free_libblock_us( &G.main->object, self->object );
3149 #endif
3150         PyObject_DEL( self );
3151 }
3152
3153 /*****************************************************************************/
3154 /* Function:    Object_compare                                           */
3155 /* Description: This is a callback function for the BPy_Object type. It  */
3156 /*              compares two Object_Type objects. Only the "==" and "!="  */
3157 /*              comparisons are meaninful. Returns 0 for equality and -1 if  */
3158 /*              they don't point to the same Blender Object struct.      */
3159 /*              In Python it becomes 1 if they are equal, 0 otherwise.   */
3160 /*****************************************************************************/
3161 static int Object_compare( BPy_Object * a, BPy_Object * b )
3162 {
3163         return ( a->object == b->object ) ? 0 : -1;
3164 }
3165
3166 /*****************************************************************************/
3167 /* Function:    Object_repr                                              */
3168 /* Description: This is a callback function for the BPy_Object type. It  */
3169 /*              builds a meaninful string to represent object objects.   */
3170 /*****************************************************************************/
3171 static PyObject *Object_repr( BPy_Object * self )
3172 {
3173         return PyString_FromFormat( "[Object \"%s\"]",
3174                                     self->object->id.name + 2 );
3175 }
3176
3177 /* Particle Deflection functions */
3178
3179 static PyObject *Object_getPIDeflection( BPy_Object * self )
3180 {  
3181     if( !self->object->pd && !setupPI(self->object) )
3182                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
3183                                 "particle deflection could not be accessed" );
3184
3185         return PyBool_FromLong( ( long ) self->object->pd->deflect );
3186 }
3187
3188 static int Object_setPIDeflection( BPy_Object * self, PyObject * value )
3189 {
3190         int param;
3191
3192     if( !self->object->pd && !setupPI(self->object) )
3193                 return EXPP_ReturnIntError( PyExc_RuntimeError,
3194                                 "particle deflection could not be accessed" );
3195
3196         param = PyObject_IsTrue( value );
3197         if( param == -1 )
3198                 return EXPP_ReturnIntError( PyExc_TypeError,
3199                                 "expected true/false argument" );
3200
3201         self->object->pd->deflect = (short)param;
3202         self->object->recalc |= OB_RECALC_OB;  
3203
3204         return 0;
3205 }
3206
3207 static PyObject *Object_getPIType( BPy_Object * self )
3208 {
3209     if( !self->object->pd && !setupPI(self->object) )
3210                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
3211                                 "particle deflection could not be accessed" );
3212
3213     return PyInt_FromLong( ( long )self->object->pd->forcefield );
3214 }
3215
3216 static int Object_setPIType( BPy_Object * self, PyObject * value )
3217 {
3218         int status;
3219         int oldforcefield;
3220
3221     if( !self->object->pd && !setupPI(self->object) )
3222                 return EXPP_ReturnIntError( PyExc_RuntimeError,
3223                                 "particle deflection could not be accessed" );
3224
3225         oldforcefield = self->object->pd->forcefield;
3226         status = EXPP_setIValueRange( value, &self->object->pd->forcefield,
3227                         PFIELD_FORCE, PFIELD_GUIDE, 'h' );
3228
3229         /*
3230          * if value was set successfully but is PFIELD_MAGNET, restore the old
3231          * value and throw exception
3232          */
3233         if( !status ) {
3234                 if ( self->object->pd->forcefield == PFIELD_MAGNET ) {
3235                         self->object->pd->forcefield = oldforcefield;
3236                         return EXPP_ReturnIntError( PyExc_ValueError,
3237                                         "PFIELD_MAGNET not supported" );
3238                 }
3239                 self->object->recalc |= OB_RECALC_OB;  
3240         }
3241         return status;
3242 }
3243
3244 static PyObject *Object_getPIUseMaxDist( BPy_Object * self )
3245 {  
3246     if( !self->object->pd && !setupPI(self->object) )
3247                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
3248                                 "particle deflection could not be accessed" );
3249
3250         return PyBool_FromLong( ( long )self->object->pd->flag );
3251 }
3252
3253 static int Object_setPIUseMaxDist( BPy_Object * self, PyObject * value )
3254 {
3255         int param;
3256
3257     if( !self->object->pd && !setupPI(self->object) )