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