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