4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
27 * The Object module provides generic access to Objects of various types via
28 * the Python interface.
31 * Contributor(s): Michel Selten, Willian Germano, Jacques Guignot,
32 * Joseph Gilbert, Stephen Swaney, Bala Gi, Campbell Barton
34 * ***** END GPL/BL DUAL LICENSE BLOCK *****
41 #include <DNA_scene_types.h>
42 #include <DNA_mesh_types.h>
43 #include <DNA_curve_types.h>
44 #include <DNA_property_types.h>
46 #include <BKE_property.h>
47 #include <BKE_mball.h>
48 #include <BIF_editview.h>
54 /* only used for oops location get/set at the moment */
55 #include "DNA_oops_types.h"
56 #include "DNA_space_types.h"
58 /*****************************************************************************/
59 /* Python API function prototypes for the Blender module. */
60 /*****************************************************************************/
61 static PyObject *M_Object_New( PyObject * self, PyObject * args );
62 PyObject *M_Object_Get( PyObject * self, PyObject * args );
63 static PyObject *M_Object_GetSelected( PyObject * self, PyObject * args );
65 /*****************************************************************************/
66 /* The following string definitions are used for documentation strings. */
67 /* In Python these will be written to the console when doing a */
68 /* Blender.Object.__doc__ */
69 /*****************************************************************************/
70 char M_Object_doc[] = "The Blender Object module\n\n\
71 This module provides access to **Object Data** in Blender.\n";
73 char M_Object_New_doc[] =
74 "(type) - Add a new object of type 'type' in the current scene";
76 char M_Object_Get_doc[] =
77 "(name) - return the object with the name 'name', returns None if not\
79 If 'name' is not specified, it returns a list of all objects in the\n\
82 char M_Object_GetSelected_doc[] =
83 "() - Returns a list of selected Objects in the active layer(s)\n\
84 The active object is the first in the list, if visible";
86 /*****************************************************************************/
87 /* Python method structure definition for Blender.Object module: */
88 /*****************************************************************************/
89 struct PyMethodDef M_Object_methods[] = {
90 {"New", ( PyCFunction ) M_Object_New, METH_VARARGS,
92 {"Get", ( PyCFunction ) M_Object_Get, METH_VARARGS,
94 {"GetSelected", ( PyCFunction ) M_Object_GetSelected, METH_VARARGS,
95 M_Object_GetSelected_doc},
99 /*****************************************************************************/
100 /* Python BPy_Object methods declarations: */
101 /*****************************************************************************/
102 static PyObject *Object_buildParts( BPy_Object * self );
103 static PyObject *Object_clearIpo( BPy_Object * self );
104 static PyObject *Object_clrParent( BPy_Object * self, PyObject * args );
105 static PyObject *Object_clearTrack( BPy_Object * self, PyObject * args );
106 static PyObject *Object_getData(BPy_Object *self, PyObject *a, PyObject *kwd);
107 static PyObject *Object_getDeltaLocation( BPy_Object * self );
108 static PyObject *Object_getDrawMode( BPy_Object * self );
109 static PyObject *Object_getDrawType( BPy_Object * self );
110 static PyObject *Object_getEuler( BPy_Object * self );
111 static PyObject *Object_getInverseMatrix( BPy_Object * self );
112 static PyObject *Object_getIpo( BPy_Object * self );
113 static PyObject *Object_getLocation( BPy_Object * self, PyObject * args );
114 static PyObject *Object_getMaterials( BPy_Object * self, PyObject * args );
115 static PyObject *Object_getMatrix( BPy_Object * self, PyObject * args );
116 static PyObject *Object_getName( BPy_Object * self );
117 static PyObject *Object_getParent( BPy_Object * self );
118 static PyObject *Object_getSize( BPy_Object * self, PyObject * args );
119 static PyObject *Object_getTimeOffset( BPy_Object * self );
120 static PyObject *Object_getTracked( BPy_Object * self );
121 static PyObject *Object_getType( BPy_Object * self );
122 static PyObject *Object_getBoundBox( BPy_Object * self );
123 static PyObject *Object_getAction( BPy_Object * self );
124 static PyObject *Object_isSelected( BPy_Object * self );
125 static PyObject *Object_makeDisplayList( BPy_Object * self );
126 static PyObject *Object_link( BPy_Object * self, PyObject * args );
127 static PyObject *Object_makeParent( BPy_Object * self, PyObject * args );
128 static PyObject *Object_materialUsage( BPy_Object * self, PyObject * args );
129 static PyObject *Object_setDeltaLocation( BPy_Object * self, PyObject * args );
130 static PyObject *Object_setDrawMode( BPy_Object * self, PyObject * args );
131 static PyObject *Object_setDrawType( BPy_Object * self, PyObject * args );
132 static PyObject *Object_setEuler( BPy_Object * self, PyObject * args );
133 static PyObject *Object_setMatrix( BPy_Object * self, PyObject * args );
134 static PyObject *Object_setIpo( BPy_Object * self, PyObject * args );
135 static PyObject *Object_setLocation( BPy_Object * self, PyObject * args );
136 static PyObject *Object_setMaterials( BPy_Object * self, PyObject * args );
137 static PyObject *Object_setName( BPy_Object * self, PyObject * args );
138 static PyObject *Object_setSize( BPy_Object * self, PyObject * args );
139 static PyObject *Object_setTimeOffset( BPy_Object * self, PyObject * args );
140 static PyObject *Object_makeTrack( BPy_Object * self, PyObject * args );
141 static PyObject *Object_shareFrom( BPy_Object * self, PyObject * args );
142 static PyObject *Object_Select( BPy_Object * self, PyObject * args );
143 static PyObject *Object_getAllProperties( BPy_Object * self );
144 static PyObject *Object_addProperty( BPy_Object * self, PyObject * args );
145 static PyObject *Object_removeProperty( BPy_Object * self, PyObject * args );
146 static PyObject *Object_getProperty( BPy_Object * self, PyObject * args );
147 static PyObject *Object_removeAllProperties( BPy_Object * self );
148 static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
150 static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * args );
151 static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args );
152 static PyObject *Object_clearScriptLinks( BPy_Object * self );
154 /*****************************************************************************/
155 /* Python BPy_Object methods table: */
156 /*****************************************************************************/
157 static PyMethodDef BPy_Object_methods[] = {
158 /* name, method, flags, doc */
159 {"buildParts", ( PyCFunction ) Object_buildParts, METH_NOARGS,
160 "Recalcs particle system (if any) "},
161 {"getIpo", ( PyCFunction ) Object_getIpo, METH_NOARGS,
162 "Returns the ipo of this object (if any) "},
163 {"clrParent", ( PyCFunction ) Object_clrParent, METH_VARARGS,
164 "Clears parent object. Optionally specify:\n\
165 mode\n\tnonzero: Keep object transform\nfast\n\t>0: Don't update scene \
166 hierarchy (faster)"},
167 {"clearTrack", ( PyCFunction ) Object_clearTrack, METH_VARARGS,
168 "Make this object not track another anymore. Optionally specify:\n\
169 mode\n\t2: Keep object transform\nfast\n\t>0: Don't update scene \
170 hierarchy (faster)"},
171 {"getData", ( PyCFunction ) Object_getData, METH_VARARGS | METH_KEYWORDS,
172 "(name_only = 0) - Returns the datablock object containing the object's \
174 If 'name_only' is nonzero or True, only the name of the datablock is returned"},
175 {"getDeltaLocation", ( PyCFunction ) Object_getDeltaLocation,
177 "Returns the object's delta location (x, y, z)"},
178 {"getDrawMode", ( PyCFunction ) Object_getDrawMode, METH_NOARGS,
179 "Returns the object draw modes"},
180 {"getDrawType", ( PyCFunction ) Object_getDrawType, METH_NOARGS,
181 "Returns the object draw type"},
182 {"getAction", ( PyCFunction ) Object_getAction, METH_NOARGS,
183 "Returns the active action for this object"},
184 {"isSelected", ( PyCFunction ) Object_isSelected, METH_NOARGS,
185 "Return a 1 or 0 depending on whether the object is selected"},
186 {"getEuler", ( PyCFunction ) Object_getEuler, METH_NOARGS,
187 "Returns the object's rotation as Euler rotation vector\n\
188 (rotX, rotY, rotZ)"},
189 {"getInverseMatrix", ( PyCFunction ) Object_getInverseMatrix,
191 "Returns the object's inverse matrix"},
192 {"getLocation", ( PyCFunction ) Object_getLocation, METH_VARARGS,
193 "Returns the object's location (x, y, z)"},
194 {"getMaterials", ( PyCFunction ) Object_getMaterials, METH_VARARGS,
195 "(i = 0) - Returns list of materials assigned to the object.\n\
196 if i is nonzero, empty slots are not ignored: they are returned as None's."},
197 {"getMatrix", ( PyCFunction ) Object_getMatrix, METH_VARARGS,
198 "(str = 'worldspace') - Returns the object matrix.\n\
199 (str = 'worldspace') - the wanted matrix: worldspace (default), localspace\n\
200 or old_worldspace.\n\
202 'old_worldspace' was the only behavior before Blender 2.34. With it the\n\
203 matrix is not updated for changes made by the script itself\n\
204 (like obj.LocX = 10) until a redraw happens, either called by the script or\n\
205 automatic when the script finishes."},
206 {"getName", ( PyCFunction ) Object_getName, METH_NOARGS,
207 "Returns the name of the object"},
208 {"getParent", ( PyCFunction ) Object_getParent, METH_NOARGS,
209 "Returns the object's parent object"},
210 {"getSize", ( PyCFunction ) Object_getSize, METH_VARARGS,
211 "Returns the object's size (x, y, z)"},
212 {"getTimeOffset", ( PyCFunction ) Object_getTimeOffset, METH_NOARGS,
213 "Returns the object's time offset"},
214 {"getTracked", ( PyCFunction ) Object_getTracked, METH_NOARGS,
215 "Returns the object's tracked object"},
216 {"getType", ( PyCFunction ) Object_getType, METH_NOARGS,
217 "Returns type of string of Object"},
218 {"getBoundBox", ( PyCFunction ) Object_getBoundBox, METH_NOARGS,
219 "Returns the object's bounding box"},
220 {"makeDisplayList", ( PyCFunction ) Object_makeDisplayList,
222 "Update this object's Display List. Some changes like turning \n\
223 'SubSurf' on for a mesh need this method (followed by a Redraw) to \n\
224 show the changes on the 3d window."},
225 {"link", ( PyCFunction ) Object_link, METH_VARARGS,
226 "Links Object with data provided in the argument. The data must \n\
227 match the Object's type, so you cannot link a Lamp to a Mesh type object."},
228 {"makeParent", ( PyCFunction ) Object_makeParent, METH_VARARGS,
229 "Makes the object the parent of the objects provided in the \n\
230 argument which must be a list of valid Objects. Optional extra arguments:\n\
231 mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
232 fast:\n\t0: update scene hierarchy automatically\n\t\
233 don't update scene hierarchy (faster). In this case, you must\n\t\
234 explicitely update the Scene hierarchy."},
235 {"materialUsage", ( PyCFunction ) Object_materialUsage, METH_VARARGS,
236 "Determines the way the material is used and returns status.\n\
237 Possible arguments (provide as strings):\n\
238 \tData: Materials assigned to the object's data are shown. (default)\n\
239 \tObject: Materials assigned to the object are shown."},
240 {"setDeltaLocation", ( PyCFunction ) Object_setDeltaLocation,
242 "Sets the object's delta location which must be a vector triple."},
243 {"setDrawMode", ( PyCFunction ) Object_setDrawMode, METH_VARARGS,
244 "Sets the object's drawing mode. The argument can be a sum of:\n\
245 2: axis\n4: texspace\n8: drawname\n16: drawimage\n32: drawwire"},
246 {"setDrawType", ( PyCFunction ) Object_setDrawType, METH_VARARGS,
247 "Sets the object's drawing type. The argument must be one of:\n\
248 1: Bounding box\n2: Wire\n3: Solid\n4: Shaded\n5: Textured"},
249 {"setEuler", ( PyCFunction ) Object_setEuler, METH_VARARGS,
250 "Set the object's rotation according to the specified Euler\n\
251 angles. The argument must be a vector triple"},
252 {"setMatrix", ( PyCFunction ) Object_setMatrix, METH_VARARGS,
253 "Set and apply a new matrix for the object"},
254 {"setLocation", ( PyCFunction ) Object_setLocation, METH_VARARGS,
255 "Set the object's location. The first argument must be a vector\n\
257 {"setMaterials", ( PyCFunction ) Object_setMaterials, METH_VARARGS,
258 "Sets materials. The argument must be a list of valid material\n\
260 {"setName", ( PyCFunction ) Object_setName, METH_VARARGS,
261 "Sets the name of the object"},
262 {"setSize", ( PyCFunction ) Object_setSize, METH_VARARGS,
263 "Set the object's size. The first argument must be a vector\n\
265 {"setTimeOffset", ( PyCFunction ) Object_setTimeOffset, METH_VARARGS,
266 "Set the object's time offset."},
267 {"makeTrack", ( PyCFunction ) Object_makeTrack, METH_VARARGS,
268 "(trackedobj, fast = 0) - Make this object track another.\n\
269 (trackedobj) - the object that will be tracked.\n\
270 (fast = 0) - if 0: update the scene hierarchy automatically. If you\n\
271 set 'fast' to a nonzero value, don't forget to update the scene yourself\n\
272 (see scene.update())."},
273 {"shareFrom", ( PyCFunction ) Object_shareFrom, METH_VARARGS,
274 "Link data of self with object specified in the argument. This\n\
275 works only if self and the object specified are of the same type."},
276 {"select", ( PyCFunction ) Object_Select, METH_VARARGS,
277 "( 1 or 0 ) - Set the selected state of the object.\n\
278 1 is selected, 0 not selected "},
279 {"setIpo", ( PyCFunction ) Object_setIpo, METH_VARARGS,
280 "(Blender Ipo) - Sets the object's ipo"},
281 {"clearIpo", ( PyCFunction ) Object_clearIpo, METH_NOARGS,
282 "() - Unlink ipo from this object"},
283 {"getAllProperties", ( PyCFunction ) Object_getAllProperties,
285 "() - Get all the properties from this object"},
286 {"addProperty", ( PyCFunction ) Object_addProperty, METH_VARARGS,
287 "() - Add a property to this object"},
288 {"removeProperty", ( PyCFunction ) Object_removeProperty, METH_VARARGS,
289 "() - Remove a property from this object"},
290 {"getProperty", ( PyCFunction ) Object_getProperty, METH_VARARGS,
291 "() - Get a property from this object by name"},
292 {"removeAllProperties", ( PyCFunction ) Object_removeAllProperties,
294 "() - removeAll a properties from this object"},
295 {"copyAllPropertiesTo", ( PyCFunction ) Object_copyAllPropertiesTo,
297 "() - copy all properties from this object to another object"},
298 {"getScriptLinks", ( PyCFunction ) Object_getScriptLinks, METH_VARARGS,
299 "(eventname) - Get a list of this object's scriptlinks (Text names) "
300 "of the given type\n"
301 "(eventname) - string: FrameChanged or Redraw."},
302 {"addScriptLink", ( PyCFunction ) Object_addScriptLink, METH_VARARGS,
303 "(text, evt) - Add a new object scriptlink.\n"
304 "(text) - string: an existing Blender Text name;\n"
305 "(evt) string: FrameChanged or Redraw."},
306 {"clearScriptLinks", ( PyCFunction ) Object_clearScriptLinks,
308 "() - Delete all scriptlinks from this object."},
309 {NULL, NULL, 0, NULL}
312 /*****************************************************************************/
313 /* PythonTypeObject callback function prototypes */
314 /*****************************************************************************/
315 static void Object_dealloc( BPy_Object * obj );
316 static PyObject *Object_getAttr( BPy_Object * obj, char *name );
317 static int Object_setAttr( BPy_Object * obj, char *name, PyObject * v );
318 static PyObject *Object_repr( BPy_Object * obj );
319 static int Object_compare( BPy_Object * a, BPy_Object * b );
321 /*****************************************************************************/
322 /* Python TypeObject structure definition. */
323 /*****************************************************************************/
324 PyTypeObject Object_Type = {
325 PyObject_HEAD_INIT( NULL ) /* requred macro */
327 "Blender Object", /* tp_name */
328 sizeof( BPy_Object ), /* tp_basicsize */
331 ( destructor ) Object_dealloc, /* tp_dealloc */
333 ( getattrfunc ) Object_getAttr, /* tp_getattr */
334 ( setattrfunc ) Object_setAttr, /* tp_setattr */
335 ( cmpfunc ) Object_compare, /* tp_compare */
336 ( reprfunc ) Object_repr, /* tp_repr */
337 0, /* tp_as_number */
338 0, /* tp_as_sequence */
339 0, /* tp_as_mapping */
344 BPy_Object_methods, /* tp_methods */
346 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
349 /*****************************************************************************/
350 /* Function: M_Object_New */
351 /* Python equivalent: Blender.Object.New */
352 /*****************************************************************************/
353 PyObject *M_Object_New( PyObject * self, PyObject * args )
355 struct Object *object;
356 BPy_Object *blen_object;
361 if( !PyArg_ParseTuple( args, "s|s", &str_type, &name ) ) {
362 EXPP_ReturnPyObjError( PyExc_TypeError,
363 "string expected as argument" );
367 if( strcmp( str_type, "Armature" ) == 0 )
369 else if( strcmp( str_type, "Camera" ) == 0 )
371 else if( strcmp( str_type, "Curve" ) == 0 )
373 /* else if (strcmp (str_type, "Text") == 0) type = OB_FONT; */
374 /* else if (strcmp (str_type, "Ika") == 0) type = OB_IKA; */
375 else if( strcmp( str_type, "Lamp" ) == 0 )
377 else if( strcmp( str_type, "Lattice" ) == 0 )
379 else if( strcmp( str_type, "Mball" ) == 0 )
381 else if( strcmp( str_type, "Mesh" ) == 0 )
383 else if( strcmp( str_type, "Surf" ) == 0 )
385 /* else if (strcmp (str_type, "Wave") == 0) type = OB_WAVE; */
386 else if( strcmp( str_type, "Empty" ) == 0 )
389 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
390 "Unknown type specified" ) );
393 /* Create a new object. */
395 /* No name is specified, set the name to the type of the object. */
398 object = alloc_libblock( &( G.main->object ), ID_OB, name );
406 QuatOne( object->quat );
407 QuatOne( object->dquat );
409 object->col[3] = 1.0; // alpha
411 object->size[0] = object->size[1] = object->size[2] = 1.0;
412 object->loc[0] = object->loc[1] = object->loc[2] = 0.0;
413 Mat4One( object->parentinv );
414 Mat4One( object->obmat );
415 object->dt = OB_SHADED; // drawtype
417 if( U.flag & USER_MAT_ON_OB ) {
418 object->colbits = -1;
420 switch ( object->type ) {
421 case OB_CAMERA: /* fall through. */
423 object->trackflag = OB_NEGZ;
424 object->upflag = OB_POSY;
427 object->trackflag = OB_POSY;
428 object->upflag = OB_POSZ;
430 object->ipoflag = OB_OFFS_OB + OB_OFFS_PARENT;
432 /* duplivert settings */
436 object->dupend = 100;
438 /* Gameengine defaults */
440 object->inertia = 1.0;
441 object->formfactor = 0.4;
442 object->damping = 0.04;
443 object->rdamping = 0.1;
444 object->anisotropicFriction[0] = 1.0;
445 object->anisotropicFriction[1] = 1.0;
446 object->anisotropicFriction[2] = 1.0;
447 object->gameflag = OB_PROP;
449 object->lay = 1; // Layer, by default visible
454 /* Create a Python object from it. */
456 ( BPy_Object * ) PyObject_NEW( BPy_Object, &Object_Type );
457 blen_object->object = object;
459 return ( ( PyObject * ) blen_object );
462 /*****************************************************************************/
463 /* Function: M_Object_Get */
464 /* Python equivalent: Blender.Object.Get */
465 /*****************************************************************************/
466 PyObject *M_Object_Get( PyObject * self, PyObject * args )
468 struct Object *object;
469 BPy_Object *blen_object;
472 PyArg_ParseTuple( args, "|s", &name );
475 object = GetObjectByName( name );
477 if( object == NULL ) {
478 /* No object exists with the name specified in the argument name. */
479 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
480 "Unknown object specified." ) );
483 ( BPy_Object * ) PyObject_NEW( BPy_Object,
485 blen_object->object = object;
487 return ( ( PyObject * ) blen_object );
489 /* No argument has been given. Return a list of all objects. */
494 obj_list = PyList_New( BLI_countlist( &( G.main->object ) ) );
496 if( obj_list == NULL ) {
497 return ( EXPP_ReturnPyObjError( PyExc_SystemError,
498 "List creation failed." ) );
501 link = G.main->object.first;
504 object = ( Object * ) link;
506 ( BPy_Object * ) PyObject_NEW( BPy_Object,
508 blen_object->object = object;
510 PyList_SetItem( obj_list, index,
511 ( PyObject * ) blen_object );
519 /*****************************************************************************/
520 /* Function: M_Object_GetSelected */
521 /* Python equivalent: Blender.Object.GetSelected */
522 /*****************************************************************************/
523 static PyObject *M_Object_GetSelected( PyObject * self, PyObject * args )
525 BPy_Object *blen_object;
530 // No 3d view has been initialized yet, simply return None
531 Py_INCREF( Py_None );
534 list = PyList_New( 0 );
535 if( ( G.scene->basact ) &&
536 ( ( G.scene->basact->flag & SELECT ) &&
537 ( G.scene->basact->lay & G.vd->lay ) ) ) {
538 /* Active object is first in the list. */
540 ( BPy_Object * ) PyObject_NEW( BPy_Object,
542 if( blen_object == NULL ) {
544 Py_INCREF( Py_None );
547 blen_object->object = G.scene->basact->object;
548 PyList_Append( list, ( PyObject * ) blen_object );
549 Py_DECREF( blen_object );
552 base_iter = G.scene->base.first;
554 if( ( ( base_iter->flag & SELECT ) &&
555 ( base_iter->lay & G.vd->lay ) ) &&
556 ( base_iter != G.scene->basact ) ) {
558 ( BPy_Object * ) PyObject_NEW( BPy_Object,
560 if( blen_object == NULL ) {
562 Py_INCREF( Py_None );
565 blen_object->object = base_iter->object;
566 PyList_Append( list, ( PyObject * ) blen_object );
567 Py_DECREF( blen_object );
569 base_iter = base_iter->next;
574 /*****************************************************************************/
575 /* Function: initObject */
576 /*****************************************************************************/
577 PyObject *Object_Init( void )
581 Object_Type.ob_type = &PyType_Type;
583 module = Py_InitModule3( "Blender.Object", M_Object_methods,
589 /*****************************************************************************/
590 /* Python BPy_Object methods: */
591 /*****************************************************************************/
593 static PyObject *Object_buildParts( BPy_Object * self )
595 void build_particle_system( Object * ob );
596 struct Object *obj = self->object;
598 build_particle_system( obj );
600 Py_INCREF( Py_None );
604 static PyObject *Object_clearIpo( BPy_Object * self )
606 Object *ob = self->object;
607 Ipo *ipo = ( Ipo * ) ob->ipo;
615 return EXPP_incr_ret_True();
618 return EXPP_incr_ret_False(); /* no ipo found */
621 static PyObject *Object_clrParent( BPy_Object * self, PyObject * args )
626 if( !PyArg_ParseTuple( args, "|ii", &mode, &fast ) ) {
627 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
628 "expected one or two integers as arguments" ) );
631 /* Remove the link only, the object is still in the scene. */
632 self->object->parent = NULL;
636 apply_obmat( self->object );
640 sort_baselist( G.scene );
643 Py_INCREF( Py_None );
647 static PyObject *Object_clearTrack( BPy_Object * self, PyObject * args )
652 if( !PyArg_ParseTuple( args, "|ii", &mode, &fast ) ) {
653 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
654 "expected one or two integers as arguments" ) );
657 /* Remove the link only, the object is still in the scene. */
658 self->object->track = NULL;
662 apply_obmat( self->object );
666 sort_baselist( G.scene );
669 Py_INCREF( Py_None );
673 /* adds object data to a Blender object, if object->data = NULL */
674 int EXPP_add_obdata( struct Object *object )
676 if( object->data != NULL )
679 switch ( object->type ) {
681 /* TODO: Do we need to add something to G? (see the OB_LAMP case) */
682 object->data = add_armature( );
685 /* TODO: Do we need to add something to G? (see the OB_LAMP case) */
686 object->data = add_camera( );
689 object->data = add_curve( OB_CURVE );
693 object->data = add_lamp( );
697 object->data = add_mesh( );
701 object->data = ( void * ) add_lattice( );
702 object->dt = OB_WIRE;
705 object->data = add_mball( );
708 /* TODO the following types will be supported later
710 object->data = add_curve(OB_SURF);
714 object->data = add_curve(OB_FONT);
717 object->data = add_ika();
718 object->dt = OB_WIRE;
721 object->data = add_wave();
735 static PyObject *Object_getData( BPy_Object *self, PyObject *a, PyObject *kwd )
737 PyObject *data_object;
738 Object *object = self->object;
740 static char *kwlist[] = {"name_only", NULL};
742 if (!PyArg_ParseTupleAndKeywords(a, kwd, "|i", kwlist, &name_only))
743 return EXPP_ReturnPyObjError( PyExc_AttributeError,
744 "expected nothing or an int (keyword 'name_only') as argument" );
746 /* if there's no obdata, try to create it */
747 if( object->data == NULL ) {
748 if( EXPP_add_obdata( object ) != 0 ) { /* couldn't create obdata */
749 Py_INCREF( Py_None );
754 /* user wants only the name of the data object */
756 ID *id = object->data;
757 data_object = Py_BuildValue("s", id->name+2);
759 if (data_object) return data_object;
760 return EXPP_ReturnPyObjError (PyExc_MemoryError,
761 "could not create a string pyobject!");
764 /* user wants the data object wrapper */
767 switch ( object->type ) {
769 data_object = Armature_CreatePyObject( object->data );
772 data_object = Camera_CreatePyObject( object->data );
775 data_object = Curve_CreatePyObject( object->data );
778 data_object = Image_CreatePyObject( object->data );
781 data_object = Ipo_CreatePyObject( object->data );
784 data_object = Lamp_CreatePyObject( object->data );
787 data_object = Lattice_CreatePyObject( object->data );
792 data_object = NMesh_CreatePyObject( object->data, object );
795 data_object = Object_CreatePyObject( object->data );
800 data_object = Text_CreatePyObject( object->data );
807 if( data_object == NULL ) {
808 Py_INCREF( Py_None );
811 return ( data_object );
815 static PyObject *Object_getDeltaLocation( BPy_Object * self )
817 PyObject *attr = Py_BuildValue( "fff",
818 self->object->dloc[0],
819 self->object->dloc[1],
820 self->object->dloc[2] );
825 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
826 "couldn't get Object.dloc attributes" ) );
829 static PyObject *Object_getDrawMode( BPy_Object * self )
831 PyObject *attr = Py_BuildValue( "b", self->object->dtx );
836 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
837 "couldn't get Object.drawMode attribute" ) );
840 static PyObject *Object_getAction( BPy_Object * self )
842 /*BPy_Action *py_action = NULL; */
844 if( !self->object->action ) {
845 Py_INCREF( Py_None );
848 return Action_CreatePyObject( self->object->action );
853 static PyObject *Object_isSelected( BPy_Object * self )
859 if( base->object == self->object ) {
860 if( base->flag & SELECT ) {
861 return EXPP_incr_ret_True();
863 return EXPP_incr_ret_False();
868 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
869 "Internal error: could not find objects selection state" ) );
873 static PyObject *Object_getDrawType( BPy_Object * self )
875 PyObject *attr = Py_BuildValue( "b", self->object->dt );
880 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
881 "couldn't get Object.drawType attribute" ) );
884 static PyObject *Object_getEuler( BPy_Object * self )
888 eul = ( EulerObject * ) newEulerObject( NULL );
889 eul->eul[0] = self->object->rot[0];
890 eul->eul[1] = self->object->rot[1];
891 eul->eul[2] = self->object->rot[2];
893 return ( PyObject * ) eul;
897 static PyObject *Object_getInverseMatrix( BPy_Object * self )
899 MatrixObject *inverse =
900 ( MatrixObject * ) newMatrixObject( NULL, 4, 4 );
901 Mat4Invert( *inverse->matrix, self->object->obmat );
903 return ( ( PyObject * ) inverse );
906 static PyObject *Object_getIpo( BPy_Object * self )
908 struct Ipo *ipo = self->object->ipo;
911 Py_INCREF( Py_None );
915 return Ipo_CreatePyObject( ipo );
918 static PyObject *Object_getLocation( BPy_Object * self, PyObject * args )
920 PyObject *attr = Py_BuildValue( "fff",
921 self->object->loc[0],
922 self->object->loc[1],
923 self->object->loc[2] );
928 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
929 "couldn't get Object.loc attributes" ) );
932 static PyObject *Object_getMaterials( BPy_Object * self, PyObject * args )
936 if( !PyArg_ParseTuple( args, "|i", &all ) ) {
937 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
938 "expected an int or nothing" ) );
941 return ( EXPP_PyList_fromMaterialList( self->object->mat,
942 self->object->totcol, all ) );
945 static PyObject *Object_getMatrix( BPy_Object * self, PyObject * args )
948 char *space = "worldspace"; /* default to world */
950 if( !PyArg_ParseTuple( args, "|s", &space ) ) {
951 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
952 "expected a string or nothing" ) );
955 matrix = newMatrixObject( NULL, 4, 4 );
957 if( BLI_streq( space, "worldspace" ) ) { /* Worldspace matrix */
958 disable_where_script( 1 );
959 where_is_object( self->object );
960 disable_where_script( 0 );
961 Mat4CpyMat4( *( ( MatrixObject * ) matrix )->matrix,
962 self->object->obmat );
963 } else if( BLI_streq( space, "localspace" ) ) { /* Localspace matrix */
964 object_to_mat4( self->object,
965 *( ( MatrixObject * ) matrix )->matrix );
966 /* old behavior, prior to 2.34, check this method's doc string: */
967 } else if( BLI_streq( space, "old_worldspace" ) ) {
968 Mat4CpyMat4( *( ( MatrixObject * ) matrix )->matrix,
969 self->object->obmat );
971 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
972 "wrong parameter, expected nothing or either 'worldspace' (default),\n\
973 'localspace' or 'old_worldspace'" ) );
978 static PyObject *Object_getName( BPy_Object * self )
980 PyObject *attr = Py_BuildValue( "s", self->object->id.name + 2 );
985 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
986 "couldn't get the name of the Object" ) );
989 static PyObject *Object_getParent( BPy_Object * self )
993 if( self->object->parent == NULL )
994 return EXPP_incr_ret( Py_None );
996 attr = Object_CreatePyObject( self->object->parent );
1002 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1003 "couldn't get Object.parent attribute" ) );
1006 static PyObject *Object_getSize( BPy_Object * self, PyObject * args )
1008 PyObject *attr = Py_BuildValue( "fff",
1009 self->object->size[0],
1010 self->object->size[1],
1011 self->object->size[2] );
1016 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1017 "couldn't get Object.size attributes" ) );
1020 static PyObject *Object_getTimeOffset( BPy_Object * self )
1022 PyObject *attr = Py_BuildValue( "f", self->object->sf );
1027 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1028 "couldn't get Object.sf attributes" ) );
1032 static PyObject *Object_getTracked( BPy_Object * self )
1036 if( self->object->track == NULL )
1037 return EXPP_incr_ret( Py_None );
1039 attr = Object_CreatePyObject( self->object->track );
1045 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1046 "couldn't get Object.track attribute" ) );
1049 static PyObject *Object_getType( BPy_Object * self )
1051 switch ( self->object->type ) {
1053 return ( Py_BuildValue( "s", "Armature" ) );
1055 return ( Py_BuildValue( "s", "Camera" ) );
1057 return ( Py_BuildValue( "s", "Curve" ) );
1059 return ( Py_BuildValue( "s", "Empty" ) );
1061 return ( Py_BuildValue( "s", "Text" ) );
1063 return ( Py_BuildValue( "s", "Ika" ) );
1065 return ( Py_BuildValue( "s", "Lamp" ) );
1067 return ( Py_BuildValue( "s", "Lattice" ) );
1069 return ( Py_BuildValue( "s", "MBall" ) );
1071 return ( Py_BuildValue( "s", "Mesh" ) );
1073 return ( Py_BuildValue( "s", "Surf" ) );
1075 return ( Py_BuildValue( "s", "Wave" ) );
1077 return ( Py_BuildValue( "s", "unknown" ) );
1082 static PyObject *Object_getBoundBox( BPy_Object * self )
1086 PyObject *vector, *bbox;
1088 if( !self->object->data )
1089 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1090 "This object isn't linked to any object data (mesh, curve, etc) yet" );
1092 if( !self->object->bb ) { /* if no ob bbox, we look in obdata */
1095 switch ( self->object->type ) {
1097 me = self->object->data;
1099 tex_space_mesh( me );
1100 vec = ( float * ) me->bb->vec;
1105 curve = self->object->data;
1107 tex_space_curve( curve );
1108 vec = ( float * ) curve->bb->vec;
1111 Py_INCREF( Py_None );
1115 { /* transform our obdata bbox by the obmat.
1116 the obmat is 4x4 homogeneous coords matrix.
1117 each bbox coord is xyz, so we make it homogenous
1118 by padding it with w=1.0 and doing the matrix mult.
1119 afterwards we divide by w to get back to xyz.
1121 /* printmatrix4( "obmat", self->object->obmat); */
1123 float tmpvec[4]; /* tmp vector for homogenous coords math */
1127 bbox = PyList_New( 8 );
1129 return EXPP_ReturnPyObjError
1130 ( PyExc_MemoryError,
1131 "couldn't create pylist" );
1132 for( i = 0, from = vec; i < 8; i++, from += 3 ) {
1133 memcpy( tmpvec, from, 3 * sizeof( float ) );
1134 tmpvec[3] = 1.0f; /* set w coord */
1135 Mat4MulVec4fl( self->object->obmat, tmpvec );
1136 /* divide x,y,z by w */
1137 tmpvec[0] /= tmpvec[3];
1138 tmpvec[1] /= tmpvec[3];
1139 tmpvec[2] /= tmpvec[3];
1142 { /* debug print stuff */
1145 printf( "\nobj bbox transformed\n" );
1146 for( i = 0; i < 4; ++i )
1147 printf( "%f ", tmpvec[i] );
1153 /* because our bounding box is calculated and
1154 does not have its own memory,
1155 we must create vectors that allocate space */
1157 vector = newVectorObject( NULL, 3 );
1158 memcpy( ( ( VectorObject * ) vector )->vec,
1159 tmpvec, 3 * sizeof( float ) );
1160 PyList_SET_ITEM( bbox, i, vector );
1163 } else { /* the ob bbox exists */
1164 vec = ( float * ) self->object->bb->vec;
1167 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1168 "couldn't retrieve bounding box data" );
1170 bbox = PyList_New( 8 );
1173 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1174 "couldn't create pylist" );
1176 /* create vectors referencing object bounding box coords */
1177 for( i = 0; i < 8; i++ ) {
1178 vector = newVectorObject( vec, 3 );
1179 PyList_SET_ITEM( bbox, i, vector );
1188 static PyObject *Object_makeDisplayList( BPy_Object * self )
1190 Object *ob = self->object;
1192 if( ob->type == OB_FONT )
1193 text_to_curve( ob, 0 );
1197 Py_INCREF( Py_None );
1201 static PyObject *Object_link( BPy_Object * self, PyObject * args )
1209 if( !PyArg_ParseTuple( args, "O", &py_data ) ) {
1210 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1211 "expected an object as argument" ) );
1213 if( Armature_CheckPyObject( py_data ) )
1214 data = ( void * ) Armature_FromPyObject( py_data );
1215 if( Camera_CheckPyObject( py_data ) )
1216 data = ( void * ) Camera_FromPyObject( py_data );
1217 if( Lamp_CheckPyObject( py_data ) )
1218 data = ( void * ) Lamp_FromPyObject( py_data );
1219 if( Curve_CheckPyObject( py_data ) )
1220 data = ( void * ) Curve_FromPyObject( py_data );
1221 if( NMesh_CheckPyObject( py_data ) )
1222 data = ( void * ) Mesh_FromPyObject( py_data, self->object );
1223 if( Lattice_CheckPyObject( py_data ) )
1224 data = ( void * ) Lattice_FromPyObject( py_data );
1225 if( Metaball_CheckPyObject( py_data ) )
1226 data = ( void * ) Metaball_FromPyObject( py_data );
1228 /* have we set data to something good? */
1230 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1231 "link argument type is not supported " ) );
1234 oldid = ( ID * ) self->object->data;
1236 obj_id = MAKE_ID2( id->name[0], id->name[1] );
1240 if( self->object->type != OB_ARMATURE ) {
1241 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1242 "The 'link' object is incompatible with the base object" ) );
1246 if( self->object->type != OB_CAMERA ) {
1247 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1248 "The 'link' object is incompatible with the base object" ) );
1252 if( self->object->type != OB_LAMP ) {
1253 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1254 "The 'link' object is incompatible with the base object" ) );
1258 if( self->object->type != OB_MESH ) {
1259 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1260 "The 'link' object is incompatible with the base object" ) );
1264 if( self->object->type != OB_CURVE ) {
1265 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1266 "The 'link' object is incompatible with the base object" ) );
1270 if( self->object->type != OB_LATTICE ) {
1271 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1272 "The 'link' object is incompatible with the base object" ) );
1276 if( self->object->type != OB_MBALL ) {
1277 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1278 "The 'link' object is incompatible with the base object" ) );
1282 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1283 "Linking this object type is not supported" ) );
1285 self->object->data = data;
1287 if( self->object->type == OB_MESH ) {
1288 self->object->totcol = 0;
1289 EXPP_synchronizeMaterialLists( self->object );
1294 if( oldid->us > 0 ) {
1297 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1298 "old object reference count below 0" ) );
1301 return EXPP_incr_ret( Py_None );
1304 static PyObject *Object_makeParent( BPy_Object * self, PyObject * args )
1308 //BPy_Object * py_obj_child; unused
1315 /* Check if the arguments passed to makeParent are valid. */
1316 if( !PyArg_ParseTuple( args, "O|ii", &list, &noninverse, &fast ) ) {
1317 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1318 "expected a list of objects and one or two integers as arguments" ) );
1320 if( !PySequence_Check( list ) ) {
1321 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1322 "expected a list of objects" ) );
1325 /* Check if the PyObject passed in list is a Blender object. */
1326 for( i = 0; i < PySequence_Length( list ); i++ ) {
1328 py_child = PySequence_GetItem( list, i );
1329 if( Object_CheckPyObject( py_child ) )
1330 child = ( Object * ) Object_FromPyObject( py_child );
1332 if( child == NULL ) {
1333 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1334 "Object Type expected" ) );
1337 parent = ( Object * ) self->object;
1338 if( test_parent_loop( parent, child ) ) {
1339 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1340 "parenting loop detected - parenting failed" ) );
1342 child->partype = PAROBJECT;
1343 child->parent = parent;
1344 //py_obj_child = (BPy_Object *) py_child;
1345 if( noninverse == 1 ) {
1346 /* Parent inverse = unity */
1347 child->loc[0] = 0.0;
1348 child->loc[1] = 0.0;
1349 child->loc[2] = 0.0;
1351 what_does_parent( child );
1352 Mat4Invert( child->parentinv, parent->obmat );
1356 sort_baselist( G.scene );
1358 // We don't need the child object anymore.
1359 //Py_DECREF ((PyObject *) child);
1361 return EXPP_incr_ret( Py_None );
1364 static PyObject *Object_materialUsage( BPy_Object * self, PyObject * args )
1366 return ( EXPP_ReturnPyObjError( PyExc_NotImplementedError,
1367 "materialUsage: not yet implemented" ) );
1370 static PyObject *Object_setDeltaLocation( BPy_Object * self, PyObject * args )
1377 if( PyObject_Length( args ) == 3 )
1378 status = PyArg_ParseTuple( args, "fff", &dloc1, &dloc2,
1381 status = PyArg_ParseTuple( args, "(fff)", &dloc1, &dloc2,
1385 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1386 "expected list argument of 3 floats" );
1388 self->object->dloc[0] = dloc1;
1389 self->object->dloc[1] = dloc2;
1390 self->object->dloc[2] = dloc3;
1392 Py_INCREF( Py_None );
1396 static PyObject *Object_setDrawMode( BPy_Object * self, PyObject * args )
1400 if( !PyArg_ParseTuple( args, "b", &dtx ) ) {
1401 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1402 "expected an integer as argument" ) );
1404 self->object->dtx = dtx;
1406 Py_INCREF( Py_None );
1410 static PyObject *Object_setDrawType( BPy_Object * self, PyObject * args )
1414 if( !PyArg_ParseTuple( args, "b", &dt ) ) {
1415 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1416 "expected an integer as argument" ) );
1418 self->object->dt = dt;
1420 Py_INCREF( Py_None );
1424 static PyObject *Object_setEuler( BPy_Object * self, PyObject * args )
1429 int status = 0; /* failure */
1433 args is either a tuple/list of floats or an euler.
1434 for backward compatibility, we also accept 3 floats.
1437 /* do we have 3 floats? */
1438 if( PyObject_Length( args ) == 3 ) {
1439 status = PyArg_ParseTuple( args, "fff", &rot1, &rot2, &rot3 );
1440 } else { //test to see if it's a list or a euler
1441 if( PyArg_ParseTuple( args, "O", &ob ) ) {
1442 if( EulerObject_Check( ob ) ) {
1443 rot1 = ( ( EulerObject * ) ob )->eul[0];
1444 rot2 = ( ( EulerObject * ) ob )->eul[1];
1445 rot3 = ( ( EulerObject * ) ob )->eul[2];
1446 status = 1; /* success! */
1447 } else if( PySequence_Check( ob ) )
1448 status = PyArg_ParseTuple( args, "(fff)",
1451 else { /* not an euler or tuple */
1453 /* python C api doc says don't decref this */
1454 /*Py_DECREF (ob); */
1456 status = 0; /* false */
1458 } else { /* arg parsing failed */
1463 if( !status ) /* parsing args failed */
1464 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1465 "expected euler or list/tuple of 3 floats " ) );
1467 self->object->rot[0] = rot1;
1468 self->object->rot[1] = rot2;
1469 self->object->rot[2] = rot3;
1471 Py_INCREF( Py_None );
1476 static PyObject *Object_setMatrix( BPy_Object * self, PyObject * args )
1481 if( !PyArg_ParseTuple( args, "O!", &matrix_Type, &mat ) )
1482 return EXPP_ReturnPyObjError
1484 "expected matrix object as argument" );
1486 for( x = 0; x < 4; x++ ) {
1487 for( y = 0; y < 4; y++ ) {
1488 self->object->obmat[x][y] = mat->matrix[x][y];
1491 apply_obmat( self->object );
1493 Py_INCREF( Py_None );
1498 static PyObject *Object_setIpo( BPy_Object * self, PyObject * args )
1500 PyObject *pyipo = 0;
1504 if( !PyArg_ParseTuple( args, "O!", &Ipo_Type, &pyipo ) )
1505 return EXPP_ReturnPyObjError( PyExc_TypeError,
1506 "expected Ipo as argument" );
1508 ipo = Ipo_FromPyObject( pyipo );
1511 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1514 if( ipo->blocktype != ID_OB )
1515 return EXPP_ReturnPyObjError( PyExc_TypeError,
1516 "this ipo is not an object ipo" );
1518 oldipo = self->object->ipo;
1520 ID *id = &oldipo->id;
1525 ( ( ID * ) & ipo->id )->us++;
1527 self->object->ipo = ipo;
1529 Py_INCREF( Py_None );
1533 static PyObject *Object_setLocation( BPy_Object * self, PyObject * args )
1540 if( PyObject_Length( args ) == 3 )
1541 status = PyArg_ParseTuple( args, "fff", &loc1, &loc2, &loc3 );
1543 status = PyArg_ParseTuple( args, "(fff)", &loc1, &loc2,
1547 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1548 "expected list argument of 3 floats" );
1550 self->object->loc[0] = loc1;
1551 self->object->loc[1] = loc2;
1552 self->object->loc[2] = loc3;
1554 Py_INCREF( Py_None );
1558 static PyObject *Object_setMaterials( BPy_Object * self, PyObject * args )
1565 if( !PyArg_ParseTuple( args, "O", &list ) ) {
1566 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1567 "expected a list of materials as argument" ) );
1570 len = PySequence_Length( list );
1572 matlist = EXPP_newMaterialList_fromPyList( list );
1574 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1575 "material list must be a list of valid materials!" ) );
1577 if( ( len < 0 ) || ( len > MAXMAT ) ) {
1578 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1579 "material list should have at least 1, at most 16 entries" ) );
1582 if( self->object->mat ) {
1583 EXPP_releaseMaterialList( self->object->mat,
1584 self->object->totcol );
1586 /* Increase the user count on all materials */
1587 for( i = 0; i < len; i++ ) {
1589 id_us_plus( ( ID * ) matlist[i] );
1591 self->object->mat = matlist;
1592 self->object->totcol = len;
1593 self->object->actcol = len;
1595 switch ( self->object->type ) {
1596 case OB_CURVE: /* fall through */
1597 case OB_FONT: /* fall through */
1598 case OB_MESH: /* fall through */
1599 case OB_MBALL: /* fall through */
1601 EXPP_synchronizeMaterialLists( self->object );
1607 return EXPP_incr_ret( Py_None );
1610 static PyObject *Object_setName( BPy_Object * self, PyObject * args )
1615 if( !PyArg_ParseTuple( args, "s", &name ) ) {
1616 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1617 "expected a String as argument" ) );
1620 PyOS_snprintf( buf, sizeof( buf ), "%s", name );
1622 rename_id( &self->object->id, buf );
1624 Py_INCREF( Py_None );
1628 static PyObject *Object_setSize( BPy_Object * self, PyObject * args )
1635 if( PyObject_Length( args ) == 3 )
1636 status = PyArg_ParseTuple( args, "fff", &sizex, &sizey,
1639 status = PyArg_ParseTuple( args, "(fff)", &sizex, &sizey,
1643 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1644 "expected list argument of 3 floats" );
1646 self->object->size[0] = sizex;
1647 self->object->size[1] = sizey;
1648 self->object->size[2] = sizez;
1650 Py_INCREF( Py_None );
1654 static PyObject *Object_setTimeOffset( BPy_Object * self, PyObject * args )
1656 float newTimeOffset;
1658 if( !PyArg_ParseTuple( args, "f", &newTimeOffset ) ) {
1659 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1660 "expected a float as argument" ) );
1663 self->object->sf = newTimeOffset;
1665 Py_INCREF( Py_None );
1669 static PyObject *Object_makeTrack( BPy_Object * self, PyObject * args )
1671 BPy_Object *tracked = NULL;
1672 Object *ob = self->object;
1675 if( !PyArg_ParseTuple( args, "O!|i", &Object_Type, &tracked, &fast ) )
1676 return EXPP_ReturnPyObjError( PyExc_TypeError,
1677 "expected an object and optionally also an int as arguments." );
1679 ob->track = tracked->object;
1682 sort_baselist( G.scene );
1684 return EXPP_incr_ret( Py_None );
1687 static PyObject *Object_shareFrom( BPy_Object * self, PyObject * args )
1693 if( !PyArg_ParseTuple( args, "O", &object ) ) {
1694 return EXPP_ReturnPyObjError( PyExc_TypeError,
1695 "expected an object argument" );
1697 if( !Object_CheckPyObject( ( PyObject * ) object ) ) {
1698 return EXPP_ReturnPyObjError( PyExc_TypeError,
1699 "first argument is not of type 'Object'" );
1702 if( self->object->type != object->object->type ) {
1703 return EXPP_ReturnPyObjError( PyExc_TypeError,
1704 "objects are not of same data type" );
1706 switch ( self->object->type ) {
1709 case OB_CAMERA: /* we can probably add the other types, too */
1714 oldid = ( ID * ) self->object->data;
1715 id = ( ID * ) object->object->data;
1716 self->object->data = object->object->data;
1718 if( self->object->type == OB_MESH && id ) {
1719 self->object->totcol = 0;
1720 EXPP_synchronizeMaterialLists( self->object );
1725 if( oldid->us > 0 ) {
1728 return ( EXPP_ReturnPyObjError
1729 ( PyExc_RuntimeError,
1730 "old object reference count below 0" ) );
1733 Py_INCREF( Py_None );
1736 return EXPP_ReturnPyObjError( PyExc_TypeError,
1737 "type not supported" );
1740 Py_INCREF( Py_None );
1746 static PyObject *Object_Select( BPy_Object * self, PyObject * args )
1752 if( !PyArg_ParseTuple( args, "i", &sel ) )
1753 return EXPP_ReturnPyObjError
1754 ( PyExc_TypeError, "expected an integer, 0 or 1" );
1757 if( base->object == self->object ) {
1759 base->flag |= SELECT;
1760 self->object->flag = base->flag;
1761 set_active_base( base );
1763 base->flag &= ~SELECT;
1764 self->object->flag = base->flag;
1773 Py_INCREF( Py_None );
1777 static PyObject *Object_getAllProperties( BPy_Object * self )
1779 PyObject *prop_list;
1780 bProperty *prop = NULL;
1782 prop_list = PyList_New( 0 );
1784 prop = self->object->prop.first;
1786 PyList_Append( prop_list, Property_CreatePyObject( prop ) );
1792 static PyObject *Object_getProperty( BPy_Object * self, PyObject * args )
1794 char *prop_name = NULL;
1795 bProperty *prop = NULL;
1796 PyObject *py_prop = Py_None;
1798 if( !PyArg_ParseTuple( args, "s", &prop_name ) ) {
1799 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1800 "expected a string" ) );
1803 prop = get_property( self->object, prop_name );
1805 py_prop = Property_CreatePyObject( prop );
1807 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1808 "couldn't find the property...." ) );
1813 static PyObject *Object_addProperty( BPy_Object * self, PyObject * args )
1815 bProperty *prop = NULL;
1816 char *prop_name = NULL;
1817 PyObject *prop_data = Py_None;
1818 char *prop_type = NULL;
1820 BPy_Property *py_prop = NULL;
1821 int argslen = PyObject_Length( args );
1823 if( argslen == 3 || argslen == 2 ) {
1824 if( !PyArg_ParseTuple
1825 ( args, "sO|s", &prop_name, &prop_data, &prop_type ) ) {
1826 return ( EXPP_ReturnPyObjError
1827 ( PyExc_AttributeError,
1828 "unable to get string, data, and optional string" ) );
1830 } else if( argslen == 1 ) {
1831 if( !PyArg_ParseTuple( args, "O!", &property_Type, &py_prop ) ) {
1832 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1833 "unable to get Property" ) );
1835 if( py_prop->property != NULL ) {
1836 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1837 "Property is already added to an object" ) );
1840 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1841 "expected 1,2 or 3 arguments" ) );
1844 //parse property type
1847 if( BLI_streq( prop_type, "BOOL" ) )
1849 else if( BLI_streq( prop_type, "INT" ) )
1851 else if( BLI_streq( prop_type, "FLOAT" ) )
1853 else if( BLI_streq( prop_type, "TIME" ) )
1855 else if( BLI_streq( prop_type, "STRING" ) )
1858 return ( EXPP_ReturnPyObjError
1859 ( PyExc_RuntimeError,
1860 "BOOL, INT, FLOAT, TIME or STRING expected" ) );
1863 if( PyInt_Check( prop_data ) )
1865 else if( PyFloat_Check( prop_data ) )
1867 else if( PyString_Check( prop_data ) )
1871 type = py_prop->type;
1874 //initialize a new bProperty of the specified type
1875 prop = new_property( type );
1879 BLI_strncpy( prop->name, prop_name, 32 );
1880 if( PyInt_Check( prop_data ) ) {
1881 *( ( int * ) &prop->data ) =
1882 ( int ) PyInt_AsLong( prop_data );
1883 } else if( PyFloat_Check( prop_data ) ) {
1884 *( ( float * ) &prop->data ) =
1885 ( float ) PyFloat_AsDouble( prop_data );
1886 } else if( PyString_Check( prop_data ) ) {
1887 BLI_strncpy( prop->poin,
1888 PyString_AsString( prop_data ),
1892 py_prop->property = prop;
1893 if( !updateProperyData( py_prop ) ) {
1894 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1895 "Could not update property data - error" ) );
1899 //add to property listbase for the object
1900 BLI_addtail( &self->object->prop, prop );
1902 return EXPP_incr_ret( Py_None );
1905 static PyObject *Object_removeProperty( BPy_Object * self, PyObject * args )
1907 char *prop_name = NULL;
1908 BPy_Property *py_prop = NULL;
1909 bProperty *prop = NULL;
1911 // we have property and no optional arg
1912 if( !PyArg_ParseTuple( args, "O!", &property_Type, &py_prop ) ) {
1913 if( !PyArg_ParseTuple( args, "s", &prop_name ) ) {
1914 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1915 "expected a Property or a string" ) );
1918 //remove the link, free the data, and update the py struct
1920 BLI_remlink( &self->object->prop, py_prop->property );
1921 if( updatePyProperty( py_prop ) ) {
1922 free_property( py_prop->property );
1923 py_prop->property = NULL;
1926 prop = get_property( self->object, prop_name );
1928 BLI_remlink( &self->object->prop, prop );
1929 free_property( prop );
1932 return EXPP_incr_ret( Py_None );
1935 static PyObject *Object_removeAllProperties( BPy_Object * self )
1937 free_properties( &self->object->prop );
1938 return EXPP_incr_ret( Py_None );
1941 static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
1944 PyObject *dest = Py_None;
1945 bProperty *prop = NULL;
1946 bProperty *propn = NULL;
1948 if( !PyArg_ParseTuple( args, "O!", &Object_Type, &dest ) ) {
1949 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1950 "expected an Object" ) );
1952 //make a copy of all it's properties
1953 prop = self->object->prop.first;
1955 propn = copy_property( prop );
1956 BLI_addtail( &( ( BPy_Object * ) dest )->object->prop, propn );
1960 return EXPP_incr_ret( Py_None );
1963 /* obj.addScriptLink */
1964 static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args )
1966 Object *obj = self->object;
1967 ScriptLink *slink = NULL;
1969 slink = &( obj )->scriptlink;
1971 if( !EXPP_addScriptLink( slink, args, 0 ) )
1972 return EXPP_incr_ret( Py_None );
1977 /* obj.clearScriptLinks */
1978 static PyObject *Object_clearScriptLinks( BPy_Object * self )
1980 Object *obj = self->object;
1981 ScriptLink *slink = NULL;
1983 slink = &( obj )->scriptlink;
1985 return EXPP_incr_ret( Py_BuildValue
1986 ( "i", EXPP_clearScriptLinks( slink ) ) );
1989 /* obj.getScriptLinks */
1990 static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * args )
1992 Object *obj = self->object;
1993 ScriptLink *slink = NULL;
1994 PyObject *ret = NULL;
1996 slink = &( obj )->scriptlink;
1998 ret = EXPP_getScriptLinks( slink, args, 0 );
2006 /*****************************************************************************/
2007 /* Function: Object_CreatePyObject */
2008 /* Description: This function will create a new BlenObject from an existing */
2009 /* Object structure. */
2010 /*****************************************************************************/
2011 PyObject *Object_CreatePyObject( struct Object * obj )
2013 BPy_Object *blen_object;
2016 return EXPP_incr_ret( Py_None );
2019 ( BPy_Object * ) PyObject_NEW( BPy_Object, &Object_Type );
2021 if( blen_object == NULL ) {
2024 blen_object->object = obj;
2025 return ( ( PyObject * ) blen_object );
2028 /*****************************************************************************/
2029 /* Function: Object_CheckPyObject */
2030 /* Description: This function returns true when the given PyObject is of the */
2031 /* type Object. Otherwise it will return false. */
2032 /*****************************************************************************/
2033 int Object_CheckPyObject( PyObject * py_obj )
2035 return ( py_obj->ob_type == &Object_Type );
2038 /*****************************************************************************/
2039 /* Function: Object_FromPyObject */
2040 /* Description: This function returns the Blender object from the given */
2042 /*****************************************************************************/
2043 struct Object *Object_FromPyObject( PyObject * py_obj )
2045 BPy_Object *blen_obj;
2047 blen_obj = ( BPy_Object * ) py_obj;
2048 return ( blen_obj->object );
2051 /*****************************************************************************/
2052 /* Description: Returns the object with the name specified by the argument */
2053 /* name. Note that the calling function has to remove the first */
2054 /* two characters of the object name. These two characters */
2055 /* specify the type of the object (OB, ME, WO, ...) */
2056 /* The function will return NULL when no object with the given */
2057 /* name is found. */
2058 /*****************************************************************************/
2059 Object *GetObjectByName( char *name )
2063 obj_iter = G.main->object.first;
2065 if( StringEqual( name, GetIdName( &( obj_iter->id ) ) ) ) {
2066 return ( obj_iter );
2068 obj_iter = obj_iter->id.next;
2071 /* There is no object with the given name */
2075 /*****************************************************************************/
2076 /* Function: Object_dealloc */
2077 /* Description: This is a callback function for the BlenObject type. It is */
2078 /* the destructor function. */
2079 /*****************************************************************************/
2080 static void Object_dealloc( BPy_Object * obj )
2082 PyObject_DEL( obj );
2085 /*****************************************************************************/
2086 /* Function: Object_getAttr */
2087 /* Description: This is a callback function for the BlenObject type. It is */
2088 /* the function that retrieves any value from Blender and */
2089 /* passes it to Python. */
2090 /*****************************************************************************/
2091 static PyObject *Object_getAttr( BPy_Object * obj, char *name )
2093 struct Object *object;
2096 object = obj->object;
2097 if( StringEqual( name, "LocX" ) )
2098 return ( PyFloat_FromDouble( object->loc[0] ) );
2099 if( StringEqual( name, "LocY" ) )
2100 return ( PyFloat_FromDouble( object->loc[1] ) );
2101 if( StringEqual( name, "LocZ" ) )
2102 return ( PyFloat_FromDouble( object->loc[2] ) );
2103 if( StringEqual( name, "loc" ) )
2104 return ( Py_BuildValue( "fff", object->loc[0], object->loc[1],
2106 if( StringEqual( name, "dLocX" ) )
2107 return ( PyFloat_FromDouble( object->dloc[0] ) );
2108 if( StringEqual( name, "dLocY" ) )
2109 return ( PyFloat_FromDouble( object->dloc[1] ) );
2110 if( StringEqual( name, "dLocZ" ) )
2111 return ( PyFloat_FromDouble( object->dloc[2] ) );
2112 if( StringEqual( name, "dloc" ) )
2113 return ( Py_BuildValue
2114 ( "fff", object->dloc[0], object->dloc[1],
2115 object->dloc[2] ) );
2116 if( StringEqual( name, "RotX" ) )
2117 return ( PyFloat_FromDouble( object->rot[0] ) );
2118 if( StringEqual( name, "RotY" ) )
2119 return ( PyFloat_FromDouble( object->rot[1] ) );
2120 if( StringEqual( name, "RotZ" ) )
2121 return ( PyFloat_FromDouble( object->rot[2] ) );
2122 if( StringEqual( name, "rot" ) )
2123 return ( Py_BuildValue( "fff", object->rot[0], object->rot[1],
2125 if( StringEqual( name, "dRotX" ) )
2126 return ( PyFloat_FromDouble( object->drot[0] ) );
2127 if( StringEqual( name, "dRotY" ) )
2128 return ( PyFloat_FromDouble( object->drot[1] ) );
2129 if( StringEqual( name, "dRotZ" ) )
2130 return ( PyFloat_FromDouble( object->drot[2] ) );
2131 if( StringEqual( name, "drot" ) )
2132 return ( Py_BuildValue
2133 ( "fff", object->drot[0], object->drot[1],
2134 object->drot[2] ) );
2135 if( StringEqual( name, "SizeX" ) )
2136 return ( PyFloat_FromDouble( object->size[0] ) );
2137 if( StringEqual( name, "SizeY" ) )
2138 return ( PyFloat_FromDouble( object->size[1] ) );
2139 if( StringEqual( name, "SizeZ" ) )
2140 return ( PyFloat_FromDouble( object->size[2] ) );
2141 if( StringEqual( name, "size" ) )
2142 return ( Py_BuildValue
2143 ( "fff", object->size[0], object->size[1],
2144 object->size[2] ) );
2145 if( StringEqual( name, "dSizeX" ) )
2146 return ( PyFloat_FromDouble( object->dsize[0] ) );
2147 if( StringEqual( name, "dSizeY" ) )
2148 return ( PyFloat_FromDouble( object->dsize[1] ) );
2149 if( StringEqual( name, "dSizeZ" ) )
2150 return ( PyFloat_FromDouble( object->dsize[2] ) );
2151 if( StringEqual( name, "dsize" ) )
2152 return ( Py_BuildValue
2153 ( "fff", object->dsize[0], object->dsize[1],
2154 object->dsize[2] ) );
2155 if( strncmp( name, "Eff", 3 ) == 0 ) {
2156 if( ( object->type == OB_IKA ) && ( object->data != NULL ) ) {
2158 switch ( name[3] ) {
2160 return ( PyFloat_FromDouble( ika->effg[0] ) );
2162 return ( PyFloat_FromDouble( ika->effg[1] ) );
2164 return ( PyFloat_FromDouble( ika->effg[2] ) );
2166 /* Do we need to display a sensible error message here? */
2172 if( StringEqual( name, "Layer" ) )
2173 return ( PyInt_FromLong( object->lay ) );
2174 if( StringEqual( name, "parent" ) ) {
2175 if( object->parent )
2176 return ( Object_CreatePyObject( object->parent ) );
2178 Py_INCREF( Py_None );
2183 if( StringEqual( name, "track" ) )
2184 return ( Object_CreatePyObject( object->track ) );
2185 if( StringEqual( name, "data" ) ) {
2186 PyObject *getdata, *tuple = PyTuple_New(0);
2189 return EXPP_ReturnPyObjError (PyExc_MemoryError,
2190 "couldn't create an empty tuple!");
2192 getdata = Object_getData( obj, tuple, NULL );
2197 if( StringEqual( name, "ipo" ) ) {
2198 if( object->ipo == NULL ) {
2199 /* There's no ipo linked to the object, return Py_None. */
2200 Py_INCREF( Py_None );
2203 return ( Ipo_CreatePyObject( object->ipo ) );
2205 if( StringEqual( name, "mat" ) || StringEqual( name, "matrix" ) )
2206 return ( Object_getMatrix
2207 ( obj, Py_BuildValue( "(s)", "worldspace" ) ) );
2208 if( StringEqual( name, "matrixWorld" ) )
2209 return ( Object_getMatrix
2210 ( obj, Py_BuildValue( "(s)", "worldspace" ) ) );
2211 if( StringEqual( name, "matrixLocal" ) )
2212 return ( Object_getMatrix
2213 ( obj, Py_BuildValue( "(s)", "localspace" ) ) );
2214 if( StringEqual( name, "colbits" ) )
2215 return ( Py_BuildValue( "h", object->colbits ) );
2216 if( StringEqual( name, "drawType" ) )
2217 return ( Py_BuildValue( "b", object->dt ) );
2218 if( StringEqual( name, "drawMode" ) )
2219 return ( Py_BuildValue( "b", object->dtx ) );
2220 if( StringEqual( name, "name" ) )
2221 return ( Py_BuildValue( "s", object->id.name + 2 ) );
2222 if( StringEqual( name, "sel" ) )
2223 return ( Object_isSelected( obj ) );
2224 if (StringEqual (name, "oopsLoc")) {
2226 Oops *oops= G.soops->oops.first;
2228 if(oops->type==ID_OB) {
2229 if ((Object *)oops->id == object) {
2230 return (Py_BuildValue ("ff", oops->x, oops->y));
2236 return EXPP_incr_ret( Py_None );
2239 /* not an attribute, search the methods table */
2240 return Py_FindMethod( BPy_Object_methods, ( PyObject * ) obj, name );
2243 /*****************************************************************************/
2244 /* Function: Object_setAttr */
2245 /* Description: This is a callback function for the BlenObject type. It is */
2246 /* the function that retrieves any value from Python and sets */
2247 /* it accordingly in Blender. */
2248 /*****************************************************************************/
2249 static int Object_setAttr( BPy_Object * obj, char *name, PyObject * value )
2252 struct Object *object;
2255 /* First put the value(s) in a tuple. For some variables, we want to */
2256 /* pass the values to a function, and these functions only accept */
2258 valtuple = Py_BuildValue( "(O)", value );
2260 return EXPP_ReturnIntError( PyExc_MemoryError,
2261 "Object_setAttr: couldn't create PyTuple" );
2264 object = obj->object;
2265 if( StringEqual( name, "LocX" ) )
2266 return ( !PyArg_Parse( value, "f", &( object->loc[0] ) ) );
2267 if( StringEqual( name, "LocY" ) )
2268 return ( !PyArg_Parse( value, "f", &( object->loc[1] ) ) );
2269 if( StringEqual( name, "LocZ" ) )
2270 return ( !PyArg_Parse( value, "f", &( object->loc[2] ) ) );
2271 if( StringEqual( name, "loc" ) ) {
2272 if( Object_setLocation( obj, valtuple ) != Py_None )
2277 if( StringEqual( name, "dLocX" ) )
2278 return ( !PyArg_Parse( value, "f", &( object->dloc[0] ) ) );
2279 if( StringEqual( name, "dLocY" ) )
2280 return ( !PyArg_Parse( value, "f", &( object->dloc[1] ) ) );
2281 if( StringEqual( name, "dLocZ" ) )
2282 return ( !PyArg_Parse( value, "f", &( object->dloc[2] ) ) );
2283 if( StringEqual( name, "dloc" ) ) {
2284 if( Object_setDeltaLocation( obj, valtuple ) != Py_None )
2289 if( StringEqual( name, "RotX" ) )
2290 return ( !PyArg_Parse( value, "f", &( object->rot[0] ) ) );
2291 if( StringEqual( name, "RotY" ) )
2292 return ( !PyArg_Parse( value, "f", &( object->rot[1] ) ) );
2293 if( StringEqual( name, "RotZ" ) )
2294 return ( !PyArg_Parse( value, "f", &( object->rot[2] ) ) );
2295 if( StringEqual( name, "rot" ) ) {
2296 if( Object_setEuler( obj, valtuple ) != Py_None )
2301 if( StringEqual( name, "dRotX" ) )
2302 return ( !PyArg_Parse( value, "f", &( object->drot[0] ) ) );
2303 if( StringEqual( name, "dRotY" ) )
2304 return ( !PyArg_Parse( value, "f", &( object->drot[1] ) ) );
2305 if( StringEqual( name, "dRotZ" ) )
2306 return ( !PyArg_Parse( value, "f", &( object->drot[2] ) ) );
2307 if( StringEqual( name, "drot" ) )
2308 return ( !PyArg_ParseTuple( value, "fff", &( object->drot[0] ),
2309 &( object->drot[1] ),
2310 &( object->drot[2] ) ) );
2311 if( StringEqual( name, "SizeX" ) )
2312 return ( !PyArg_Parse( value, "f", &( object->size[0] ) ) );
2313 if( StringEqual( name, "SizeY" ) )
2314 return ( !PyArg_Parse( value, "f", &( object->size[1] ) ) );
2315 if( StringEqual( name, "SizeZ" ) )
2316 return ( !PyArg_Parse( value, "f", &( object->size[2] ) ) );
2317 if( StringEqual( name, "size" ) )
2318 return ( !PyArg_ParseTuple( value, "fff", &( object->size[0] ),
2319 &( object->size[1] ),
2320 &( object->size[2] ) ) );
2321 if( StringEqual( name, "dSizeX" ) )
2322 return ( !PyArg_Parse( value, "f", &( object->dsize[0] ) ) );
2323 if( StringEqual( name, "dSizeY" ) )
2324 return ( !PyArg_Parse( value, "f", &( object->dsize[1] ) ) );
2325 if( StringEqual( name, "dSizeZ" ) )
2326 return ( !PyArg_Parse( value, "f", &( object->dsize[2] ) ) );
2327 if( StringEqual( name, "dsize" ) )
2328 return ( !PyArg_ParseTuple
2329 ( value, "fff", &( object->dsize[0] ),
2330 &( object->dsize[1] ), &( object->dsize[2] ) ) );
2331 if( strncmp( name, "Eff", 3 ) == 0 ) {
2332 if( ( object->type == OB_IKA ) && ( object->data != NULL ) ) {
2334 switch ( name[3] ) {
2336 return ( !PyArg_Parse
2337 ( value, "f", &( ika->effg[0] ) ) );
2339 return ( !PyArg_Parse
2340 ( value, "f", &( ika->effg[1] ) ) );
2342 return ( !PyArg_Parse
2343 ( value, "f", &( ika->effg[2] ) ) );
2345 /* Do we need to display a sensible error message here? */
2351 if( StringEqual( name, "Layer" ) ) {
2352 /* usage note: caller of this func needs to do a
2353 Blender.Redraw(-1) to update and redraw the interface */
2359 if( ! PyArg_Parse( value, "i", &newLayer ) ) {
2360 return EXPP_ReturnIntError( PyExc_AttributeError,
2361 "expected int as bitmask" );
2364 /* uppper 2 nibbles are for local view */
2365 newLayer &= 0x00FFFFFF;
2366 if( newLayer == 0 ) /* bail if nothing to do */
2369 /* update any bases pointing to our object */
2370 base = FIRSTBASE; /* first base in current scene */
2372 if( base->object == obj->object ) {
2373 local = base->lay &= 0xFF000000;
2374 base->lay = local | newLayer;
2375 object->lay = base->lay;
2383 if( StringEqual( name, "parent" ) ) {
2384 /* This is not allowed. */
2385 EXPP_ReturnPyObjError( PyExc_AttributeError,
2386 "Setting the parent is not allowed." );
2389 if( StringEqual( name, "track" ) ) {
2390 if( Object_makeTrack( obj, valtuple ) != Py_None )
2395 if( StringEqual( name, "data" ) ) {
2396 /* This is not allowed. */
2397 EXPP_ReturnPyObjError( PyExc_AttributeError,
2398 "Setting the data is not allowed." );
2401 if( StringEqual( name, "ipo" ) ) {
2402 /* This is not allowed. */
2403 EXPP_ReturnPyObjError( PyExc_AttributeError,
2404 "Setting the ipo is not allowed." );
2407 if( StringEqual( name, "mat" ) ) {
2408 /* This is not allowed. */
2409 EXPP_ReturnPyObjError( PyExc_AttributeError,
2410 "Setting the matrix is not allowed." );
2413 if( StringEqual( name, "matrix" ) ) {
2414 /* This is not allowed. */
2415 EXPP_ReturnPyObjError( PyExc_AttributeError,
2416 "Please use .setMatrix(matrix)" );
2419 if( StringEqual( name, "colbits" ) )
2420 return ( !PyArg_Parse( value, "h", &( object->colbits ) ) );
2421 if( StringEqual( name, "drawType" ) ) {
2422 if( Object_setDrawType( obj, valtuple ) != Py_None )
2427 if( StringEqual( name, "drawMode" ) ) {
2428 if( Object_setDrawMode( obj, valtuple ) != Py_None )
2433 if( StringEqual( name, "name" ) ) {
2434 if( Object_setName( obj, valtuple ) != Py_None )
2439 if( StringEqual( name, "sel" ) ) {
2440 if( Object_Select( obj, valtuple ) != Py_None )
2445 if (StringEqual (name, "oopsLoc")) {
2447 Oops *oops= G.soops->oops.first;
2449 if(oops->type==ID_OB) {
2450 if ((Object *)oops->id == object) {
2451 return (!PyArg_ParseTuple (value, "ff", &(oops->x),&(oops->y)));
2460 return EXPP_ReturnIntError( PyExc_KeyError, "attribute not found" );
2463 /*****************************************************************************/
2464 /* Function: Object_compare */
2465 /* Description: This is a callback function for the BPy_Object type. It */
2466 /* compares two Object_Type objects. Only the "==" and "!=" */
2467 /* comparisons are meaninful. Returns 0 for equality and -1 if */
2468 /* they don't point to the same Blender Object struct. */
2469 /* In Python it becomes 1 if they are equal, 0 otherwise. */
2470 /*****************************************************************************/
2471 static int Object_compare( BPy_Object * a, BPy_Object * b )
2473 Object *pa = a->object, *pb = b->object;
2474 return ( pa == pb ) ? 0 : -1;
2477 /*****************************************************************************/
2478 /* Function: Object_repr */
2479 /* Description: This is a callback function for the BPy_Object type. It */
2480 /* builds a meaninful string to represent object objects. */
2481 /*****************************************************************************/
2482 static PyObject *Object_repr( BPy_Object * self )
2484 return PyString_FromFormat( "[Object \"%s\"]",
2485 self->object->id.name + 2 );