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