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