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