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