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