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