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