| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | /** Object module; access to Object objects in Blender
 | 
					
						
							|  |  |  |   * $Id$ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. The Blender | 
					
						
							|  |  |  |  * Foundation also sells licenses for use in proprietary software under | 
					
						
							|  |  |  |  * the Blender License.  See http://www.blender.org/BL/ for information
 | 
					
						
							|  |  |  |  * about this. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is: all of this file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): none yet. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL/BL DUAL LICENSE BLOCK ***** | 
					
						
							|  |  |  |   * | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | #include "BPY_macros.h"
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | #include "opy_vector.h" /* matrix datatypes */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "b_interface.h" // most datatypes
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "opy_datablock.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_arithb.h" /* Mat4Invert */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-25 12:02:15 +00:00
										 |  |  | #ifdef HAVE_CONFIG_H
 | 
					
						
							|  |  |  | #include <config.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | /* PROTOS */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ------------------------------------------------------------------------ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************/ | 
					
						
							|  |  |  | /* Object properties for access by datablock code */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define NULLFUNC 0
 | 
					
						
							|  |  |  | #define NULLHANDLING 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* structure: see opy_datablock.h */ | 
					
						
							|  |  |  | /* attrname, DNA_membername, type      stype, min,  max, index,dlist,    
 | 
					
						
							|  |  |  | 		handlingflag, extra1Ptr, extra2Ptr, extra3Ptr */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty Object_Properties[]= { | 
					
						
							|  |  |  | 	{"LocX",	"loc[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {0}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"LocY",	"loc[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {1}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"LocZ",	"loc[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {2}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"loc",		"loc[3]",	DBP_TYPE_VEC, 0, 3.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"dLocX",	"dloc[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {0}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"dLocY",	"dloc[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {1}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"dLocZ",	"dloc[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {2}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"dloc",	"dloc[3]",	DBP_TYPE_VEC, 0, 3.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"RotX",	"rot[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {0}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"RotY",	"rot[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {1}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"RotZ",	"rot[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {2}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"rot",		"rot[3]",	DBP_TYPE_VEC, 0, 3.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"dRotX",	"drot[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {0}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"dRotY",	"drot[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {1}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"dRotZ",	"drot[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {2}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"drot",	"drot[3]",	DBP_TYPE_VEC, 0, 3.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"SizeX",	"size[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {0}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"SizeY",	"size[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {1}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"SizeZ",	"size[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {2}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"size",	"size[3]",	DBP_TYPE_VEC, 0, 3.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"dSizeX",	"dsize[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {0}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"dSizeY",	"dsize[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {1}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"dSizeZ",	"dsize[3]",	DBP_TYPE_FLO, 0, 0.0,	0.0, {2}, {3, -sizeof(float)}},  | 
					
						
							|  |  |  | 	{"dsize",	"dsize[3]",	DBP_TYPE_VEC, 0, 3.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"EffX",	"effx",		DBP_TYPE_FLO, DBP_TYPE_FUN, 0.0,	0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr},  | 
					
						
							|  |  |  | 	{"EffY",	"effy",		DBP_TYPE_FLO, DBP_TYPE_FUN, 0.0,	0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr},  | 
					
						
							|  |  |  | 	{"EffZ",	"effz",		DBP_TYPE_FLO, DBP_TYPE_FUN, 0.0,	0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"Layer",	"layer",	DBP_TYPE_INT, DBP_TYPE_FUN, 0.0,	0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr},  | 
					
						
							|  |  |  | 	{"layer",	"layer",	DBP_TYPE_INT, DBP_TYPE_FUN, 0.0,	0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"parent",	"*parent",	DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	{"track",	"*track",	DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	{"data",	"*data",	DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"mat",		"matrix",		DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, newMatrixObject},  | 
					
						
							|  |  |  | 	{"matrix",		"matrix",		DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, newMatrixObject},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"colbits",	"colbits",	DBP_TYPE_SHO, 0, 0.0,	0.0},   | 
					
						
							|  |  |  | 	{"drawType",	"dt",	DBP_TYPE_CHA, 0, 0.0,	0.0},   | 
					
						
							|  |  |  | 	{"drawMode",	"dtx",	DBP_TYPE_CHA, 0, 0.0,	0.0},   | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*************************/ | 
					
						
							|  |  |  | /* Object module methods */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_GET(Objectmodule, object, getObjectList()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char Objectmodule_New_doc[] = "(type) - Add a new object of type 'type' in the current scene"; | 
					
						
							|  |  |  | static PyObject *Objectmodule_New(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *ob; | 
					
						
							|  |  |  | 	int type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTuple(args, "i", &type)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, "type expected"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	/* add object */ | 
					
						
							|  |  |  | 	ob = object_new(type); | 
					
						
							|  |  |  | 	return DataBlock_fromData(ob); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Objectmodule_getSelected_doc[]= | 
					
						
							|  |  |  | "() - Returns a list of selected Objects in the active layer(s)\n\
 | 
					
						
							|  |  |  | The active object is the first in the list, if visible"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Objectmodule_getSelected (PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *ob, *list; | 
					
						
							|  |  |  | 	Base *base; | 
					
						
							|  |  |  | 	Object *tmp; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	list= PyList_New(0); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (ActiveBase && SelectedAndLayer(ActiveBase)) { | 
					
						
							|  |  |  | 		tmp = ActiveObject; /* active object is first in list */ | 
					
						
							|  |  |  | 		if (!tmp) goto no_selection; | 
					
						
							|  |  |  | 		ob = DataBlock_fromData(tmp); | 
					
						
							|  |  |  | 		PyList_Append(list, ob); Py_DECREF(ob); // because previous call increfs
 | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	base = FirstBase; | 
					
						
							|  |  |  | 	while (base) { | 
					
						
							|  |  |  | 		if (SelectedAndLayer(base) && base != ActiveBase) { | 
					
						
							|  |  |  | 			PyObject *ob = DataBlock_fromData(ObjectfromBase(base)); | 
					
						
							|  |  |  | 			if (!ob) goto no_selection; | 
					
						
							|  |  |  | 			PyList_Append(list, ob); Py_DECREF(ob);  | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		base= base->next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return list; | 
					
						
							|  |  |  | no_selection: | 
					
						
							|  |  |  | 	Py_DECREF(list); | 
					
						
							|  |  |  | 	Py_INCREF(Py_None); | 
					
						
							|  |  |  | 	return Py_None; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct PyMethodDef Objectmodule_methods[] = { | 
					
						
							|  |  |  | 	{"New",			Objectmodule_New,			METH_VARARGS, Objectmodule_New_doc}, | 
					
						
							|  |  |  | 	// emulation :
 | 
					
						
							|  |  |  | 	{"Get",			Objectmodule_get,			METH_VARARGS, Objectmodule_get_doc}, // XXX
 | 
					
						
							|  |  |  | 	{"get",			Objectmodule_get,			METH_VARARGS, Objectmodule_get_doc}, | 
					
						
							|  |  |  | 	{"getSelected", Objectmodule_getSelected,	METH_VARARGS, Objectmodule_getSelected_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*************************/ | 
					
						
							|  |  |  | /* Object object methods */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Object_get is defined as macro; see opy_datablock.h */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_getType_doc[] = "() - returns Object type"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_getType(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *ob= PYBLOCK_AS_OBJECT(self); | 
					
						
							|  |  |  | 	return Py_BuildValue("i", (short) ob->type); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_getMatrix_doc[] = "() - returns 4D matrix of object"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_getMatrix(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *ob= PYBLOCK_AS_OBJECT(self); | 
					
						
							|  |  |  | 	return newMatrixObject(ob->obmat); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_getInverseMatrix_doc[] = "() - returns inverse 4D matrix of object"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_getInverseMatrix(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *ob= PYBLOCK_AS_OBJECT(self); | 
					
						
							|  |  |  | 	float inverse[4][4]; | 
					
						
							|  |  |  | 	Mat4Invert(inverse, ob->obmat); | 
					
						
							|  |  |  | 	return newMatrixObject(inverse); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_clrParent_doc[]=  | 
					
						
							|  |  |  | "(mode = 0, fast = 0) - clears parent object.\n\
 | 
					
						
							|  |  |  | If specified:\n\ | 
					
						
							|  |  |  |    mode   2: keep object transform\n\ | 
					
						
							|  |  |  |    fast > 0: don't update scene hierarchy (faster)\n\ | 
					
						
							|  |  |  | "; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_clrParent(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int mode = 0, ret; | 
					
						
							|  |  |  | 	int fast = 0; | 
					
						
							|  |  |  | 	Object *ob= PYBLOCK_AS_OBJECT(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BPY_TRY(PyArg_ParseTuple(args, "|ii",  &mode, &fast)); | 
					
						
							|  |  |  | 	ret = object_clrParent(ob, mode, fast); | 
					
						
							|  |  |  | 	return Py_BuildValue("i", ret); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_ASSIGN_IPO(Object, object) // defines Object_assignIpo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_makeParent_doc[]= | 
					
						
							|  |  |  | "([obj1, obj2, ...], mode = 0, fast = 0) - makes 'self' a parent of the\n\
 | 
					
						
							|  |  |  | objects in the list.\n\ | 
					
						
							|  |  |  | If specified:\n\ | 
					
						
							|  |  |  |     mode <> 0: do not clear parent inverse\n\ | 
					
						
							|  |  |  |     fast <> 0      : do not update scene hierarchy (faster)\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | If fast is set, you will have to call Scene.getCurrent.update() before\n\ | 
					
						
							|  |  |  | redraw."; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_makeParent(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, ret; | 
					
						
							|  |  |  | 	PyObject *list; | 
					
						
							|  |  |  | 	int noninverse = 0; | 
					
						
							|  |  |  | 	int fast = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DataBlock *parblk = (DataBlock*) self; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BPY_TRY(PyArg_ParseTuple(args, "O|ii", &list, &noninverse, &fast)); | 
					
						
							|  |  |  | 	if (!PySequence_Check(list)){ | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, "expects a list of objects"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < PySequence_Length(list); i ++) { | 
					
						
							|  |  |  | 		DataBlock *childblk = (DataBlock *) PySequence_GetItem(list, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!DataBlock_Check(childblk)) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_TypeError, "Object Type expected"); | 
					
						
							|  |  |  | 			 return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ret = object_makeParent((Object *) parblk->data, (Object *) childblk->data, noninverse, fast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Py_DECREF((PyObject *) childblk); // don't need it anymore
 | 
					
						
							|  |  |  | 		if (ret == 0) { // could not parent
 | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_RuntimeError, "parenting failed!"); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		}	 | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (PyErr_Occurred()) { | 
					
						
							|  |  |  | 		PyErr_Print(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return Py_BuildValue("i", 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_getMaterials_doc[] = "() - returns a list of object materials"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_getMaterials(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	DataBlock *objectblk = (DataBlock*) self; | 
					
						
							|  |  |  | 	Object *object = PYBLOCK_AS_OBJECT(objectblk); | 
					
						
							|  |  |  | 	return PyList_fromMaterialList(object->mat, object->totcol); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_setMaterials_doc[] = "(materialList) - sets object materials"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_setMaterials(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int len; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	DataBlock *objectblk = (DataBlock*) self; | 
					
						
							|  |  |  | 	Object *object = PYBLOCK_AS_OBJECT(objectblk); | 
					
						
							|  |  |  | 	PyObject *list; | 
					
						
							|  |  |  | 	Material **matlist; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BPY_TRY(PyArg_ParseTuple(args, "O!", &PyList_Type, &list)); | 
					
						
							|  |  |  | 	len = PySequence_Length(list); | 
					
						
							|  |  |  | 	if (len) { | 
					
						
							|  |  |  | 		matlist = newMaterialList_fromPyList(list); | 
					
						
							|  |  |  | 		if (!matlist) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_TypeError,  | 
					
						
							|  |  |  | 			"materialList must be a list of valid materials!"); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ret = object_setMaterials(object, matlist, len); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ret = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return Py_BuildValue("i", ret); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_copy_doc[] = "() - returns a copy of the object, sharing the same data"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_copy(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DataBlock *objectblk = (DataBlock*) self; | 
					
						
							|  |  |  | 	Object *object = PYBLOCK_AS_OBJECT(objectblk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	new = object_copy(object); | 
					
						
							|  |  |  | 	return DataBlock_fromData(new); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Object_shareFrom_doc[] = "(obj) - link data of 'self' with data of 'obj' -- \n\
 | 
					
						
							|  |  |  | only if of same type!"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *Object_shareFrom(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	DataBlock *blockA = (DataBlock*) self; | 
					
						
							|  |  |  | 	DataBlock *blockB; | 
					
						
							|  |  |  | 	Object *object, *other; | 
					
						
							|  |  |  | 	int t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &blockB)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!DataBlock_isType(blockB, ID_OB)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, "Argument 1 is not of type 'Object'"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	object = PYBLOCK_AS_OBJECT(blockA); | 
					
						
							|  |  |  | 	other  = PYBLOCK_AS_OBJECT(blockB); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (other->type != object->type) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, "Objects are not of same data type"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	t = object->type; | 
					
						
							|  |  |  | 	switch (t) { | 
					
						
							|  |  |  | 		case OB_MESH: | 
					
						
							|  |  |  | 			return Py_BuildValue("i", object_linkdata(object, other->data)); | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_TypeError, "Type not supported"); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /******************/ | 
					
						
							|  |  |  | /* get & set attr */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static float g_zero_float= 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Object attributes functions which require getter/setter C functions 
 | 
					
						
							|  |  |  |    different from the access provided by DataBlock support */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* get special attributes through datablock property structure */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void *Object_special_getattr(void *vdata, char *name)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *ob= (Object *) vdata; | 
					
						
							|  |  |  | 	int scriptflag; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (STREQ(name, "layer")) { | 
					
						
							|  |  |  | 		return &ob->lay; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	} else if (strncmp(name, "eff", 3)==0) { | 
					
						
							|  |  |  | 		Ika *ika= ob->data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (ob->type==OB_IKA && ika) { | 
					
						
							|  |  |  | 			if      (name[3]=='x') return &ika->effg[0]; | 
					
						
							|  |  |  | 			else if (name[3]=='y') return &ika->effg[1]; | 
					
						
							|  |  |  | 			else if (name[3]=='z') return &ika->effg[2]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		return &g_zero_float; | 
					
						
							|  |  |  | 	/* these only for compatibiliy... XXX */ | 
					
						
							|  |  |  | 	} else if (STREQ(name, "matrix")) { | 
					
						
							|  |  |  | 		scriptflag = during_script(); | 
					
						
							|  |  |  | 		disable_where_script(1); | 
					
						
							|  |  |  | 		where_is_object(ob); | 
					
						
							|  |  |  | 		disable_where_script(scriptflag); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		return &ob->obmat; | 
					
						
							|  |  |  | 	} else if (STREQ(name, "inverse") || STREQ(name, "inverseMatrix")) { | 
					
						
							|  |  |  | 		return Object_getInverseMatrix(vdata, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* end compatibility */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	PyErr_SetString(PyExc_AttributeError, name); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Object_special_setattr(void *vdata, char *name, PyObject *py_ob) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *ob= (Object *) vdata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (STREQ(name, "layer")) { | 
					
						
							|  |  |  | 		Base *base; | 
					
						
							|  |  |  | 		int ival; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (!PyArg_Parse(py_ob, "i", &ival)) return -1; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		ob->lay= ival; | 
					
						
							|  |  |  | 	// TODO this is old stuff, maybe move to update routine at end of
 | 
					
						
							|  |  |  | 	// script execution ?
 | 
					
						
							|  |  |  | 		base= (G.scene->base.first); | 
					
						
							|  |  |  | 		while (base) { | 
					
						
							|  |  |  | 			if (base->object == ob) base->lay= ob->lay; | 
					
						
							|  |  |  | 			base= base->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	// end TODO
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} else if (strncmp(name, "eff", 3)==0) { | 
					
						
							|  |  |  | 		Ika *ika= ob->data; | 
					
						
							|  |  |  | 		float fval; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (!PyArg_Parse(py_ob, "f", &fval)) return -1; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (ob->type==OB_IKA && ika) { | 
					
						
							|  |  |  | 			if (name[3]=='x') ika->effg[0]= fval; | 
					
						
							|  |  |  | 			else if (name[3]=='y') ika->effg[1]= fval; | 
					
						
							|  |  |  | 			else if (name[3]=='z') ika->effg[2]= fval; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			itterate_ika(ob); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyErr_SetString(PyExc_AttributeError, name); | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef MethodDef
 | 
					
						
							|  |  |  | #define MethodDef(func) _MethodDef(func, Object)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct PyMethodDef Object_methods[] = { | 
					
						
							|  |  |  | 	MethodDef(makeParent), | 
					
						
							|  |  |  | 	MethodDef(copy), | 
					
						
							|  |  |  | 	MethodDef(shareFrom), | 
					
						
							|  |  |  | 	MethodDef(getMatrix), | 
					
						
							|  |  |  | 	MethodDef(getType), | 
					
						
							|  |  |  | 	MethodDef(getInverseMatrix), | 
					
						
							|  |  |  | 	MethodDef(clrParent), | 
					
						
							|  |  |  | 	MethodDef(assignIpo), | 
					
						
							|  |  |  | 	MethodDef(clrIpo), | 
					
						
							|  |  |  | 	MethodDef(getMaterials), | 
					
						
							|  |  |  | 	MethodDef(setMaterials), | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef BPY_ADDCONST
 | 
					
						
							|  |  |  | #define BPY_ADDCONST(dict, name) insertConst(dict, #name, PyInt_FromLong(OB_##name))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *initObject(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *mod, *dict, *d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Object", Objectmodule_methods); | 
					
						
							|  |  |  | 	dict= PyModule_GetDict(mod); | 
					
						
							|  |  |  | 	d = ConstObject_New(); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Types", d); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, EMPTY); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, MESH); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, LAMP); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, CAMERA); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	d = ConstObject_New(); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "DrawTypes", d); | 
					
						
							|  |  |  | 	/* dt flags */ | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, BOUNDBOX); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, WIRE); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SOLID); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SHADED); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, TEXTURE); | 
					
						
							|  |  |  | 	d = ConstObject_New(); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "DrawModes", d); | 
					
						
							|  |  |  | 	/* dtx flags */ | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, BOUNDBOX); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, AXIS); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, TEXSPACE); | 
					
						
							|  |  |  | 	insertConst(d, "NAME", PyInt_FromLong(OB_DRAWNAME)); | 
					
						
							|  |  |  | 	return mod; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |