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