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