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