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