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