| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | /* Datablock handling code. This handles the generic low level access to Blender
 | 
					
						
							|  |  |  |    Datablocks. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * $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 ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************
 | 
					
						
							|  |  |  |  * This code provides low level, generalized access to the Blender Datablock  | 
					
						
							|  |  |  |  * objects. It basically creates a descriptor Python Object of type 'DataBlock' | 
					
						
							|  |  |  |  * for each requested Blender datablock. | 
					
						
							|  |  |  |  * This introduces the question of synchronization, for example: | 
					
						
							|  |  |  |  *  What happens if an Object is deleted? | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Blender Objects have their own 'reference counting', e.g. a Mesh datablock | 
					
						
							|  |  |  |  * used by two Objects has a user count of 2. Datablocks with user count of 0 | 
					
						
							|  |  |  |  * are not saved to Disk -- this is the current way Blender does | 
					
						
							|  |  |  |  * 'garbage collection' | 
					
						
							|  |  |  |  * Therefore, an object should normally not be deleted by Python, but rather | 
					
						
							|  |  |  |  * unlinked from its parent object. | 
					
						
							|  |  |  |  * Still, for other objects like Scene or Text objects, deletion from 'Main' | 
					
						
							|  |  |  |  * is desired. | 
					
						
							|  |  |  |  * The current workaround: | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |  * Some objects can be explicitely deleted (not recommended, but possible) -- | 
					
						
							|  |  |  |  * they have a user count of 1, even if they are used by objects in some way, | 
					
						
							|  |  |  |  * for example Text objects which are used by any other Blender object | 
					
						
							|  |  |  |  * through a ScriptLink. | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Objects that are deleted through Python end up with a 'dead' descriptor; | 
					
						
							|  |  |  |  * accessing the descriptor after deletion causes a Python exception. | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * NASTY UGLY DIRTY, VUILE, DRECKIGES AND STILL REMAINING PROBLEM: | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * It is (in the current API) possible to construct the case, that an | 
					
						
							|  |  |  |  * Object is deleted in Blender, but the Python descriptor does not know | 
					
						
							|  |  |  |  * about this. Accessing the descriptor (which simply contains a pointer to | 
					
						
							|  |  |  |  * the raw datablock struct) will most probably end in colourful joy. | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * TODO: | 
					
						
							|  |  |  |  * possible solutions: | 
					
						
							|  |  |  |  * - rewrite datablock handling that way, that the descriptor uses an id  | 
					
						
							|  |  |  |  *   tag to retrieve that pointer through a getPointerbyID() function  | 
					
						
							|  |  |  |  *   (if the object exists!) on each access. Slow. | 
					
						
							|  |  |  |  * - make sure that deletion always happends by the descriptor and never | 
					
						
							|  |  |  |  *   delete the raw datastructure. This solution would imply a major | 
					
						
							|  |  |  |  *   redesign of user action handling (GUI actions calling python). | 
					
						
							|  |  |  |  *   Not likely to happen...better fusion raw and python object in this case. | 
					
						
							|  |  |  |  *   After all, still somewhat dirty. | 
					
						
							|  |  |  |  * - make sure that no deletion can happen in Blender while a script | 
					
						
							|  |  |  |  *   still accesses the raw data - i.e. implement user counting of raw | 
					
						
							|  |  |  |  *   objects with descriptors. This would need an implementation of | 
					
						
							|  |  |  |  *   garbage collection in Blender. This might sound like the most feasible | 
					
						
							|  |  |  |  *   solution... | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | #include "BPY_macros.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "opy_datablock.h"
 | 
					
						
							|  |  |  | #include "opy_nmesh.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "opy_vector.h" /* matrix datatypes */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BPY_tools.h"
 | 
					
						
							|  |  |  | #include "BPY_types.h"
 | 
					
						
							|  |  |  | #include "BPY_main.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "b_interface.h" /* needed for most of the DNA datatypes */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-25 12:02:15 +00:00
										 |  |  | #ifdef HAVE_CONFIG_H
 | 
					
						
							|  |  |  | #include <config.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ---------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************/ | 
					
						
							|  |  |  | /* Camera Datablocks */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_GET(Cameramodule, camera, getCameraList()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Cameramodule_New_doc[] =  | 
					
						
							|  |  |  | "() - returns new Camera object";  | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | PyObject *Cameramodule_New (PyObject *self, PyObject *args)  | 
					
						
							|  |  |  | {  | 
					
						
							|  |  |  | 	Camera *obj;  | 
					
						
							|  |  |  | 	obj = camera_new();  | 
					
						
							|  |  |  | 	return DataBlock_fromData(obj);  | 
					
						
							|  |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef FUTURE_PYTHON_API
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty Camera_Properties[]= { | 
					
						
							|  |  |  | 	{"lens",	"lens",		DBP_TYPE_FLO, 0, 1.0,    250.0},  | 
					
						
							|  |  |  | 	{"clipStart","clipsta",	DBP_TYPE_FLO, 0, 0.0,    100.0},  | 
					
						
							|  |  |  | 	{"clipEnd",	"clipend",	DBP_TYPE_FLO, 0, 1.0,   5000.0},  | 
					
						
							|  |  |  | 	{"type", "type",        DBP_TYPE_SHO, 0, 0.0,      0.0}, | 
					
						
							|  |  |  | 	{"mode", "flag",        DBP_TYPE_SHO, 0, 0.0,      0.0}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty Camera_Properties[]= { | 
					
						
							|  |  |  | 	{"Lens",	"lens",		DBP_TYPE_FLO, 0, 1.0,	250.0},  | 
					
						
							|  |  |  | 	{"ClSta",	"clipsta",	DBP_TYPE_FLO, 0, 0.0,	100.0},  | 
					
						
							|  |  |  | 	{"ClEnd",	"clipend",	DBP_TYPE_FLO, 0, 1.0,	5000.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef Cameramodule_methods[] = { | 
					
						
							|  |  |  | 	{"New", Cameramodule_New, METH_VARARGS, Cameramodule_New_doc}, | 
					
						
							|  |  |  | 	{"get", Cameramodule_get, METH_VARARGS, Cameramodule_get_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_ASSIGN_IPO(Camera, camera) // defines Camera_assignIpo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef Camera_methods[] = { | 
					
						
							|  |  |  | 	{"clrIpo", Camera_clrIpo, METH_VARARGS, Camera_clrIpo_doc}, | 
					
						
							|  |  |  | 	{"assignIpo", Camera_assignIpo, METH_VARARGS, Camera_assignIpo_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***********************/ | 
					
						
							|  |  |  | /* Material Datablocks */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** returns a pointer to a new (malloced) material list created from
 | 
					
						
							|  |  |  |   * a Python material list | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Material **newMaterialList_fromPyList(PyObject *list) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, len; | 
					
						
							|  |  |  | 	DataBlock *block = 0; | 
					
						
							|  |  |  | 	Material *mat; | 
					
						
							|  |  |  | 	Material **matlist; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	len = PySequence_Length(list); | 
					
						
							|  |  |  | 	if (len > 16) len = 16; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	matlist = newMaterialList(len); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (i= 0; i < len; i++) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		block= (DataBlock *) PySequence_GetItem(list, i); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (DataBlock_isType(block, ID_MA)) { | 
					
						
							|  |  |  | 			mat = (Material *) block->data; | 
					
						
							|  |  |  | 			matlist[i] = mat; | 
					
						
							|  |  |  | 		} else {  | 
					
						
							|  |  |  | 			// error; illegal type in material list
 | 
					
						
							|  |  |  | 			Py_DECREF(block); | 
					
						
							|  |  |  | 			MEM_freeN(matlist); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		}	 | 
					
						
							|  |  |  | 		Py_DECREF(block); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return matlist; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Return Python List from material pointer list 'matlist' with length
 | 
					
						
							|  |  |  |   * 'len' | 
					
						
							|  |  |  |   * | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *PyList_fromMaterialList(Material **matlist, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *list; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	list = PyList_New(0); | 
					
						
							|  |  |  | 	if (!matlist) return list; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < len; i++) { | 
					
						
							|  |  |  | 		Material *mat= matlist[i]; | 
					
						
							|  |  |  | 		PyObject *ob; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (mat) { | 
					
						
							|  |  |  | 			ob = DataBlock_fromData(mat); | 
					
						
							|  |  |  | 			PyList_Append(list, ob); | 
					
						
							|  |  |  | 			Py_DECREF(ob); // because Append increfs!
 | 
					
						
							|  |  |  | 		}			 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return list; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_GET(Materialmodule, material, getMaterialList()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_NEW(Materialmodule, Material, material_new()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef Materialmodule_methods[] = { | 
					
						
							|  |  |  | 	{"get", Materialmodule_get, METH_VARARGS, Materialmodule_get_doc}, | 
					
						
							|  |  |  | 	{"New", Materialmodule_New, METH_VARARGS, Materialmodule_New_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_ASSIGN_IPO(Material, material)    | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef Material_methods[] = { | 
					
						
							|  |  |  | 	{"clrIpo", Material_clrIpo, METH_VARARGS, Material_clrIpo_doc}, | 
					
						
							|  |  |  | 	{"assignIpo", Material_assignIpo, METH_VARARGS, Material_assignIpo_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef FUTURE_PYTHON_API
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty Material_Properties[]= { | 
					
						
							|  |  |  | 	{"R",		"r",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"G",		"g",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"B",		"b",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"specR",	"specr",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"specG",	"specg",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"specB",	"specb",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"mirR",	"mirr",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"mirG",	"mirg",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"mirB",	"mirb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"ref",		"ref",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"alpha",	"alpha",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"emit",	"emit",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"amb",		"amb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"spec",	"spec",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"specTransp",	"spectra",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"haloSize",	"hasize",	DBP_TYPE_FLO, 0, 0.0,	10000.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"mode",	"mode",		DBP_TYPE_INT, 0, 0.0,	0.0},     | 
					
						
							|  |  |  | 	{"hard",	"har",		DBP_TYPE_SHO, 0, 1.0,	128.0},   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{NULL}  | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty Material_Properties[]= { | 
					
						
							|  |  |  | 	{"R",		"r",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"G",		"g",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"B",		"b",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"SpecR",	"specr",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"SpecG",	"specg",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"SpecB",	"specb",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"MirR",	"mirr",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"MirG",	"mirg",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"MirB",	"mirb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"Ref",		"ref",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"Alpha",	"alpha",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"Emit",	"emit",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"Amb",		"amb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"Spec",	"spec",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"SpTra",	"spectra",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"HaSize",	"hasize",	DBP_TYPE_FLO, 0, 0.0,	10000.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"Mode",	"mode",		DBP_TYPE_INT, 0, 0.0,	0.0},   | 
					
						
							|  |  |  | 	{"Hard",	"har",		DBP_TYPE_SHO, 0, 1.0,	128.0},   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{NULL}  | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************/ | 
					
						
							|  |  |  | /* Lamp Datablocks */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_GET(Lampmodule, lamp, getLampList()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // DATABLOCK_NEW(Lampmodule, Lamp, lamp_new())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Lampmodule_New_doc[] =  | 
					
						
							|  |  |  | "() - returns new Lamp object";  | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | PyObject *Lampmodule_New (PyObject *self, PyObject *args)  | 
					
						
							|  |  |  | {  | 
					
						
							|  |  |  | 	Lamp *obj;  | 
					
						
							|  |  |  | 	obj = lamp_new();  | 
					
						
							|  |  |  | 	return DataBlock_fromData(obj);  | 
					
						
							|  |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef FUTURE_PYTHON_API
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty Lamp_Properties[]= { | 
					
						
							|  |  |  | 	{"mode",	"mode",			DBP_TYPE_SHO, 0, 0.0,	0.0},  | 
					
						
							|  |  |  | 	{"type",	"type",			DBP_TYPE_SHO, 0, 0.0,	0.0},  | 
					
						
							|  |  |  | 	{"R",		"r",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"G",		"g",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"B",		"b",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"energy",	"energy",		DBP_TYPE_FLO, 0, 0.0,	10.0},  | 
					
						
							|  |  |  | 	{"dist",	"dist",			DBP_TYPE_FLO, 0, 0.01,	5000.0},  | 
					
						
							|  |  |  | 	{"spotSize",	"spotsize",		DBP_TYPE_FLO, 0, 1.0,	180.0},  | 
					
						
							|  |  |  | 	{"spotBlend",	"spotblend",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"haloInt",	"haint",		DBP_TYPE_FLO, 0, 0.0,	5.0},  | 
					
						
							|  |  |  | 	{"quad1",	"att1",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"quad2",	"att2",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"bufferSize",	"bufsize",	DBP_TYPE_SHO, 0, 0.0,	0.0},  | 
					
						
							|  |  |  | 	{"samples",	"samp",	DBP_TYPE_SHO, 0, 1.0,	16.0},  | 
					
						
							|  |  |  | 	{"haloStep",	"shadhalostep",	DBP_TYPE_SHO, 0, 0.0,	12.0},  | 
					
						
							|  |  |  | 	{"clipStart",	"clipsta",	DBP_TYPE_FLO, 0, 0.1,	5000.0},  | 
					
						
							|  |  |  | 	{"clipEnd",	"clipend",	DBP_TYPE_FLO, 0, 0.1,	5000.0},  | 
					
						
							|  |  |  | 	{"bias",	"bias",	DBP_TYPE_FLO, 0, 0.01,	5.0},  | 
					
						
							|  |  |  | 	{"softness",	"soft",	DBP_TYPE_FLO, 0, 1.00,	100.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty Lamp_Properties[]= { | 
					
						
							|  |  |  | 	{"mode",	"mode",			DBP_TYPE_SHO, 0, 0.0,	0.0},  | 
					
						
							|  |  |  | 	{"type",	"type",			DBP_TYPE_SHO, 0, 0.0,	0.0},  | 
					
						
							|  |  |  | 	{"R",		"r",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"G",		"g",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"B",		"b",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"Energ",	"energy",		DBP_TYPE_FLO, 0, 0.0,	10.0},  | 
					
						
							|  |  |  | 	{"Dist",	"dist",			DBP_TYPE_FLO, 0, 0.01,	5000.0},  | 
					
						
							|  |  |  | 	{"SpotSi",	"spotsize",		DBP_TYPE_FLO, 0, 1.0,	180.0},  | 
					
						
							|  |  |  | 	{"SpotBl",	"spotblend",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"HaloInt",	"haint",		DBP_TYPE_FLO, 0, 1.0,	5.0},  | 
					
						
							|  |  |  | 	{"Quad1",	"att1",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"Quad2",	"att2",			DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef Lampmodule_methods[] = { | 
					
						
							|  |  |  | 	{"New", Lampmodule_New, METH_VARARGS, Lampmodule_New_doc}, | 
					
						
							|  |  |  | 	{"get", Lampmodule_get, METH_VARARGS, Lampmodule_get_doc}, | 
					
						
							|  |  |  | #ifdef CURRENT_PYTHON_API
 | 
					
						
							|  |  |  | 	{"Get", Lampmodule_get, METH_VARARGS, Lampmodule_get_doc}, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_ASSIGN_IPO(Lamp, lamp) // defines Lamp_assignIpo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef Lamp_methods[] = { | 
					
						
							|  |  |  | 	{"clrIpo", Lamp_clrIpo, METH_VARARGS, Lamp_clrIpo_doc}, | 
					
						
							|  |  |  | 	{"assignIpo", Lamp_assignIpo, METH_VARARGS, Lamp_assignIpo_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************/ | 
					
						
							|  |  |  | /* World Datablocks */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DATABLOCK_GET(Worldmodule, world, getWorldList() ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef FUTURE_PYTHON_API
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty World_Properties[]= { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"mode", "mode", DBP_TYPE_SHO, 0, 0.0,  0.0}, | 
					
						
							|  |  |  | 	{"skyType", "skytype", DBP_TYPE_SHO, 0, 0.0,  0.0}, | 
					
						
							|  |  |  | 	{"mistType", "mistype", DBP_TYPE_SHO, 0, 0.0,  0.0}, | 
					
						
							|  |  |  | 	{"horR",	"horr",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"horG",	"horg",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"horB",	"horb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"ambR",	"ambr",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"ambG",	"ambg",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"ambB",	"ambb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"zenR",	"zenr",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"zenG",	"zeng",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"zenB",	"zenb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"exposure",	"exposure",	DBP_TYPE_FLO, 0, 0.0,	5.0},  | 
					
						
							|  |  |  | 	{"mistStart",	"miststa",	DBP_TYPE_FLO, 0, 0.0,	1000.0},  | 
					
						
							|  |  |  | 	{"mistDepth",	"mistdist",	DBP_TYPE_FLO, 0, 0.0,	1000.0},  | 
					
						
							|  |  |  | 	{"mistHeight",	"misthi",	DBP_TYPE_FLO, 0, 0.0,	100.0},  | 
					
						
							|  |  |  | 	{"starDensity",	"stardist",	DBP_TYPE_FLO, 0, 2.0,	1000.0},  | 
					
						
							|  |  |  | 	{"starMinDist",	"starmindist",	DBP_TYPE_FLO, 0, 0.0,	1000.0},  | 
					
						
							|  |  |  | 	{"starSize",	"starsize",	DBP_TYPE_FLO, 0, 0.0,	10.0},  | 
					
						
							|  |  |  | 	{"starColNoise",	"starcolsize",	DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"gravity",	"gravity",	DBP_TYPE_FLO, 0, 0.0,	25.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DataBlockProperty World_Properties[]= { | 
					
						
							|  |  |  | 	{"HorR",	"horr",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"HorG",	"horg",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"HorB",	"horb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"ZenR",	"zenr",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"ZenG",	"zeng",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"ZenB",	"zenb",		DBP_TYPE_FLO, 0, 0.0,	1.0},  | 
					
						
							|  |  |  | 	{"Expos",	"exposure",	DBP_TYPE_FLO, 0, 0.0,	5.0},  | 
					
						
							|  |  |  | 	{"MisSta",	"miststa",	DBP_TYPE_FLO, 0, 0.0,	1000.0},  | 
					
						
							|  |  |  | 	{"MisDi",	"mistdist",	DBP_TYPE_FLO, 0, 0.0,	1000.0},  | 
					
						
							|  |  |  | 	{"MisHi",	"misthi",	DBP_TYPE_FLO, 0, 0.0,	100.0},  | 
					
						
							|  |  |  | 	{"StarDi",	"stardist",	DBP_TYPE_FLO, 0, 2.0,	1000.0},  | 
					
						
							|  |  |  | 	{"StarSi",	"starsize",	DBP_TYPE_FLO, 0, 0.0,	10.0},  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{"ipo",		"*ipo",		DBP_TYPE_FUN, 0, 0.0,	0.0, {0}, {0}, 0, 0, get_DataBlock_func},  | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char Worldmodule_getActive_doc[]="() - Returns the active world"; | 
					
						
							|  |  |  | static PyObject *Worldmodule_getActive (PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (scene_getCurrent()->world)  | 
					
						
							|  |  |  | 		return DataBlock_fromData(scene_getCurrent()->world); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return BPY_incr_ret(Py_None);	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef Worldmodule_methods[] = { | 
					
						
							|  |  |  | 	// these for compatibility...
 | 
					
						
							|  |  |  | 	{"get",			Worldmodule_get,			METH_VARARGS, Worldmodule_get_doc}, | 
					
						
							|  |  |  | #ifdef CURRENT_PYTHON_API
 | 
					
						
							|  |  |  | 	{"Get",			Worldmodule_get,			METH_VARARGS, Worldmodule_get_doc}, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	{"getCurrent",	Worldmodule_getActive,	METH_VARARGS, Worldmodule_getActive_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* XXX these should go elsewhere */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *BPY_PyList_FromIDList(ListBase *list, DBConvertfunc convertfunc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *pylist= PyList_New(BLI_countlist(list)); | 
					
						
							|  |  |  | 	ID *id = list->first; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int i=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (id) { | 
					
						
							|  |  |  | 		PyObject *ob= convertfunc(id); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (!ob) { | 
					
						
							|  |  |  | 			Py_DECREF(pylist); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		PyList_SetItem(pylist, i, ob);	 | 
					
						
							|  |  |  | 		id = id->next; i++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return pylist; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *py_find_from_list(ListBase *list, PyObject *args) { | 
					
						
							|  |  |  | 	char *name= NULL; | 
					
						
							|  |  |  | 	ID *id = list->first; | 
					
						
							|  |  |  | 	BPY_TRY(PyArg_ParseTuple(args, "|s", &name)); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (name) { | 
					
						
							|  |  |  | 		while (id) { | 
					
						
							|  |  |  | 			if (strcmp(name, getIDName(id))==0)  | 
					
						
							|  |  |  | 				return DataBlock_fromData(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			id= id->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return BPY_incr_ret(Py_None); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	} else  | 
					
						
							|  |  |  | 		return BPY_PyList_FromIDList(list, DataBlock_fromData); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *named_enum_get(int val, NamedEnum *enums) { | 
					
						
							|  |  |  | 	while (enums->name) { | 
					
						
							|  |  |  | 		if (enums->num == val) return PyString_FromString(enums->name); | 
					
						
							|  |  |  | 		enums++; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	PyErr_SetString(PyExc_AttributeError, "Internal error, Unknown enumerated type"); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int named_enum_set(char *name, NamedEnum *enums) { | 
					
						
							|  |  |  | 	while (enums->name) { | 
					
						
							|  |  |  | 		if (STREQ(enums->name, name))  | 
					
						
							|  |  |  | 			return enums->num; | 
					
						
							|  |  |  | 		enums++; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int calc_offset_subsize(int *dlist, int *idx, int *subsize) { | 
					
						
							|  |  |  | 	int n= *dlist; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (n<=0) { | 
					
						
							|  |  |  | 		*subsize= -n; | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		int ss; | 
					
						
							|  |  |  | 		int off= calc_offset_subsize(dlist+1, idx+1, &ss); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 		*subsize= n*ss; | 
					
						
							|  |  |  | 		return off + (*idx)*ss; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int calc_offset(int *dlist, int *idx) { | 
					
						
							|  |  |  | 	int subsize; | 
					
						
							|  |  |  | 	return calc_offset_subsize(dlist, idx, &subsize); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void *get_db_ptr(DataBlockProperty *prop, char *structname, void *struct_ptr) { | 
					
						
							|  |  |  | 	int offset= BLO_findstruct_offset(structname, prop->struct_name); | 
					
						
							|  |  |  | 	void *ptr= struct_ptr; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (offset==-1) { | 
					
						
							|  |  |  | 		BPY_warn(("Internal error, Invalid prop entry\n")); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ptr= (void *) (((char *)ptr) + offset); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	offset= calc_offset(prop->dlist, prop->idx);	 | 
					
						
							|  |  |  | 	ptr= (void *) (((char *)ptr) + offset); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return ptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *datablock_getattr(DataBlockProperty *props, char *structname, char *name, void *struct_ptr) {	 | 
					
						
							|  |  |  | 	if (STREQ(name, "properties") || STREQ(name, "__members__")) { | 
					
						
							|  |  |  | 		PyObject *l= PyList_New(0); | 
					
						
							|  |  |  | 		DataBlockProperty *p= props; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		while (p->public_name) { | 
					
						
							|  |  |  | 			PyList_Append(l, PyString_FromString(p->public_name)); | 
					
						
							|  |  |  | 			p++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		return l; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	while (props->public_name) { | 
					
						
							|  |  |  | 		if (STREQ(name, props->public_name)) { | 
					
						
							|  |  |  | 			void *ptr = struct_ptr; | 
					
						
							|  |  |  | 			int val; | 
					
						
							|  |  |  | 			DBPtrToObFP conv_fp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (props->handling==DBP_HANDLING_NONE ||  | 
					
						
							|  |  |  | 					props->handling==DBP_HANDLING_NENM) { | 
					
						
							|  |  |  | 				ptr= get_db_ptr(props, structname, struct_ptr); | 
					
						
							|  |  |  | 				if (!ptr) return NULL; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 			} else if (props->handling==DBP_HANDLING_FUNC) { | 
					
						
							|  |  |  | 				DBGetPtrFP fp= (DBGetPtrFP) props->extra1; | 
					
						
							|  |  |  | 				ptr= fp(struct_ptr, props->struct_name, 0); | 
					
						
							|  |  |  | 				if (!ptr) return NULL; | 
					
						
							|  |  |  | 			}			 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			switch(props->type) { | 
					
						
							|  |  |  | 			case DBP_TYPE_CHA: | 
					
						
							|  |  |  | 				val= *((char	*)ptr); | 
					
						
							|  |  |  | 				if (props->handling==DBP_HANDLING_NENM)  | 
					
						
							|  |  |  | 					return named_enum_get(val, props->extra1);				 | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					return PyInt_FromLong(val); | 
					
						
							|  |  |  | 			case DBP_TYPE_SHO: | 
					
						
							|  |  |  | 				val= *((short	*)ptr); | 
					
						
							|  |  |  | 				if (props->handling==DBP_HANDLING_NENM)  | 
					
						
							|  |  |  | 					return named_enum_get(val, props->extra1);				 | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					return PyInt_FromLong(val); | 
					
						
							|  |  |  | 			case DBP_TYPE_INT: | 
					
						
							|  |  |  | 				val= *((int	*)ptr); | 
					
						
							|  |  |  | 				if (props->handling==DBP_HANDLING_NENM)  | 
					
						
							|  |  |  | 					return named_enum_get(val, props->extra1);				 | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					return PyInt_FromLong(val); | 
					
						
							|  |  |  | 			case DBP_TYPE_FLO: | 
					
						
							|  |  |  | 				return PyFloat_FromDouble	( *((float	*)ptr) ); | 
					
						
							|  |  |  | 			case DBP_TYPE_VEC: | 
					
						
							|  |  |  | 				return newVectorObject		( ((float	*)ptr), (int) props->min ); | 
					
						
							|  |  |  | 			case DBP_TYPE_FUN: | 
					
						
							|  |  |  | 				conv_fp= (DBPtrToObFP) props->extra2; | 
					
						
							|  |  |  | 				return conv_fp( ptr ); | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_AttributeError, "Internal error, Unknown prop type"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		props++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	PyErr_SetString(PyExc_AttributeError, name); | 
					
						
							|  |  |  | 	return NULL;		 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int datablock_setattr(DataBlockProperty *props, char *structname, char *name, void *struct_ptr, PyObject *setto) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (props->public_name) { | 
					
						
							|  |  |  | 		if (STREQ(props->public_name, name)) { | 
					
						
							|  |  |  | 			void *ptr = NULL; | 
					
						
							|  |  |  | 			int type; | 
					
						
							|  |  |  | 			DBSetPtrFP conv_fp; | 
					
						
							|  |  |  | 			int clamp= props->min!=props->max; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			int enum_val= -1; | 
					
						
							|  |  |  | 			char	cha_data; | 
					
						
							|  |  |  | 			short	sho_data; | 
					
						
							|  |  |  | 			int		int_data; | 
					
						
							|  |  |  | 			float	flo_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			type= props->stype; | 
					
						
							|  |  |  | 			if (type==DBP_TYPE_NON) type= props->type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (props->handling==DBP_HANDLING_NONE) { | 
					
						
							|  |  |  | 				ptr= get_db_ptr(props, structname, struct_ptr); | 
					
						
							|  |  |  | 				if (!ptr) return 0; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 			} else if (props->handling==DBP_HANDLING_FUNC) { | 
					
						
							|  |  |  | 				if (type!=DBP_TYPE_FUN) { | 
					
						
							|  |  |  | 					DBGetPtrFP fp= (DBGetPtrFP) props->extra1; | 
					
						
							|  |  |  | 					ptr= fp(struct_ptr, props->struct_name, 1); | 
					
						
							|  |  |  | 					if (!ptr) return 0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if (props->handling==DBP_HANDLING_NENM) { | 
					
						
							|  |  |  | 				char *str; | 
					
						
							|  |  |  | 				if (!PyArg_Parse(setto, "s", &str)) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				ptr= get_db_ptr(props, structname, struct_ptr); | 
					
						
							|  |  |  | 				if (!ptr) return 0; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				enum_val= named_enum_set(str, props->extra1); | 
					
						
							|  |  |  | 				if (enum_val==-1) | 
					
						
							|  |  |  | 					return py_err_ret_int(PyExc_AttributeError, "invalid setting for field"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			switch(type) { | 
					
						
							|  |  |  | 			case DBP_TYPE_CHA: | 
					
						
							|  |  |  | 				if (enum_val==-1) { | 
					
						
							|  |  |  | 					if (!PyArg_Parse(setto, "b", &cha_data)) return -1; | 
					
						
							|  |  |  | 				} else cha_data= (char) enum_val; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				if (clamp) { | 
					
						
							|  |  |  | 					CLAMP(cha_data, (char) props->min, (char) props->max); | 
					
						
							|  |  |  | 				}	 | 
					
						
							|  |  |  | 				*((char		*)ptr)= cha_data; | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			case DBP_TYPE_SHO: | 
					
						
							|  |  |  | 				if (enum_val==-1) { | 
					
						
							|  |  |  | 					if (!PyArg_Parse(setto, "h", &sho_data)) return -1; | 
					
						
							|  |  |  | 				} else sho_data= (short) enum_val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (clamp) { | 
					
						
							|  |  |  | 					CLAMP(sho_data, (short) props->min, (short) props->max); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				*((short	*)ptr)= sho_data; | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			case DBP_TYPE_INT: | 
					
						
							|  |  |  | 				if (enum_val==-1) { | 
					
						
							|  |  |  | 					if (!PyArg_Parse(setto, "i", &int_data)) return -1; | 
					
						
							|  |  |  | 				} else int_data= (int) enum_val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (clamp) { | 
					
						
							|  |  |  | 					CLAMP(int_data, (int) props->min, (int) props->max); | 
					
						
							|  |  |  | 				}	 | 
					
						
							|  |  |  | 				*((int		*)ptr)= int_data; | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			case DBP_TYPE_FLO: | 
					
						
							|  |  |  | 				if (!PyArg_Parse(setto, "f", &flo_data)) return -1; | 
					
						
							|  |  |  | 				if (clamp) { | 
					
						
							|  |  |  | 					CLAMP(flo_data, (float) props->min, (float) props->max); | 
					
						
							|  |  |  | 				}		 | 
					
						
							|  |  |  | 				*((float	*)ptr)= flo_data; | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			case DBP_TYPE_VEC: | 
					
						
							|  |  |  | 			/* this is very dangerous!! TYPE_VEC also can contain non floats; see
 | 
					
						
							|  |  |  | 			 * ipo curve attribute h1t, etc. */ | 
					
						
							|  |  |  | 				if (props->min == 3.0 ) {  // vector triple
 | 
					
						
							|  |  |  | 					return BPY_parsefloatvector(setto, (float *) ptr, 3); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					return py_err_ret_int(PyExc_AttributeError, "cannot directly assign, use slice assignment instead"); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 			case DBP_TYPE_FUN: | 
					
						
							|  |  |  | 				conv_fp= (DBSetPtrFP) props->extra3; | 
					
						
							|  |  |  | 				if (conv_fp) | 
					
						
							|  |  |  | 					return conv_fp( struct_ptr, props->struct_name, setto ); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					return py_err_ret_int(PyExc_AttributeError, "cannot directly assign to item"); | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_AttributeError, "Internal error, Unknown prop type"); | 
					
						
							|  |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		props++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyErr_SetString(PyExc_AttributeError, name); | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *datablock_assignIpo(DataBlock *block, DataBlock *ipoblock) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Ipo **ipoptr; | 
					
						
							|  |  |  | 	Ipo *ipo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!DataBlock_isType(ipoblock, ID_IP)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, "expects Ipo object"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ipo = PYBLOCK_AS_IPO(ipoblock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (DataBlock_type(block) != ipo->blocktype) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, "Ipo type does not match object type!"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ipoptr = get_db_ptr(block->properties, "ipo", block->data); | 
					
						
							|  |  |  | 	if (!ipoptr) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_RuntimeError, "Object does not have an ipo!"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*ipoptr = ipo; | 
					
						
							|  |  |  | 	Py_INCREF(Py_None); | 
					
						
							|  |  |  | 	return Py_None;	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* deallocates a Python Datablock object */ | 
					
						
							|  |  |  | void DataBlock_dealloc(DataBlock *self)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef REF_USERCOUNT
 | 
					
						
							|  |  |  | 	BOB_XDECUSER(DATABLOCK_ID(self)); // XXX abuse for ref count
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	PyMem_DEL(self); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *DataBlock_repr(DataBlock *self)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static char s[256]; | 
					
						
							|  |  |  | 	if (self->data)  | 
					
						
							|  |  |  | 		sprintf (s, "[%.32s %.32s]", self->type, getIDName((ID*)self->data)); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		sprintf (s, "[%.32s %.32s]", self->type, "<deleted>"); | 
					
						
							|  |  |  | 	return Py_BuildValue("s", s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | /* datablock linking */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Link data to Object */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *link_Data_toObject(DataBlock *objectblk, DataBlock *datablk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *object = PYBLOCK_AS_OBJECT(objectblk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void *data = datablk->data; | 
					
						
							|  |  |  | 	if (!object_linkdata(object, data)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  | 		"Object type different from Data type or linking for this type\
 | 
					
						
							|  |  |  |  not supported"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	Py_INCREF(Py_None);	 | 
					
						
							|  |  |  | 	return Py_None; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_NMESH
 | 
					
						
							|  |  |  | /** Special function to link NMesh data to an Object */ | 
					
						
							|  |  |  | static PyObject *link_NMesh_toObject(DataBlock *objectblk, NMesh *nmesh) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int retval; | 
					
						
							|  |  |  | 	Mesh *mesh = nmesh->mesh; | 
					
						
							|  |  |  | 	Object *obj = PYBLOCK_AS_OBJECT(objectblk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// if mesh was not created yet (mesh == 0), then do so:
 | 
					
						
							|  |  |  | 	if (!mesh) { | 
					
						
							|  |  |  | 		mesh = Mesh_fromNMesh(nmesh); // create and convert data
 | 
					
						
							|  |  |  | 		nmesh->mesh = mesh; | 
					
						
							|  |  |  | 		nmesh_updateMaterials(nmesh); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	retval = object_linkdata(obj, mesh); | 
					
						
							|  |  |  | 	if (!retval) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_RuntimeError, "failed to link NMesh data"); | 
					
						
							|  |  |  | 		if (!mesh) | 
					
						
							|  |  |  | 			printf("mesh data was null\n"); // XXX
 | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	synchronizeMaterialLists(obj, obj->data); | 
					
						
							|  |  |  | 	return Py_BuildValue("i", retval); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** This is the generic function for linking objects with each other.
 | 
					
						
							|  |  |  |   * It can be called on any DataBlock, as long as this makes sense. | 
					
						
							|  |  |  |   * Example: | 
					
						
							|  |  |  |   *  | 
					
						
							|  |  |  |   * from Blender import Object, Scene, NMesh | 
					
						
							|  |  |  |   * ob = Object.get("Plane") | 
					
						
							|  |  |  |   * scene = Scene.get("2") | 
					
						
							|  |  |  |   * ob.link(scene) | 
					
						
							|  |  |  |   * | 
					
						
							|  |  |  |   *    or | 
					
						
							|  |  |  |   * | 
					
						
							|  |  |  |   *	nmesh = NMesh.GetRaw('Mesh') | 
					
						
							|  |  |  |   * ob.link(nmesh)  # instanciate mesh | 
					
						
							|  |  |  |   * | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char DataBlock_link_doc[]= | 
					
						
							|  |  |  | "(object) - Links 'self' with the specified object.\n\
 | 
					
						
							|  |  |  | Only the following object types can be linked to each other:\n\ | 
					
						
							|  |  |  | 	Scene  -> Object\n\ | 
					
						
							|  |  |  |     Object -> Data (Mesh, Curve, etc.)\n\ | 
					
						
							|  |  |  |     Object -> Materials: [Material1, Material2, ...]\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | The order of linking does not matter, i.e. the following both expressions\n\ | 
					
						
							|  |  |  | are valid:\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  |     scene.link(object)\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  |     object.link(scene)\n\ | 
					
						
							|  |  |  | "; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | PyObject *DataBlock_link(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	DataBlock *blockA= (DataBlock*) self; | 
					
						
							|  |  |  | 	PyObject *with; | 
					
						
							|  |  |  | 	DataBlock *blockB; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_NMESH
 | 
					
						
							|  |  |  | 	BPY_TRY(PyArg_ParseTuple(args, "O", &with)); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	blockB = (DataBlock *) with; | 
					
						
							|  |  |  | #else	
 | 
					
						
							|  |  |  | 	BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &blockB)); | 
					
						
							|  |  |  | #endif	
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (DataBlock_type(blockA)) { | 
					
						
							|  |  |  | 		case ID_OB: | 
					
						
							|  |  |  | 	// NMesh is no datablock object, so needs special treatment:
 | 
					
						
							|  |  |  | #ifdef USE_NMESH
 | 
					
						
							|  |  |  | 			if (NMesh_Check(with)) { | 
					
						
							|  |  |  | 				return link_NMesh_toObject(blockA, (NMesh *) with); | 
					
						
							|  |  |  | 			}	 | 
					
						
							|  |  |  | #endif	
 | 
					
						
							|  |  |  | 			if (!DataBlock_Check(blockB)) { | 
					
						
							|  |  |  | 				PyErr_SetString(PyExc_TypeError, "Argument must be a DataBlock object!"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			}	 | 
					
						
							|  |  |  | 			return link_Data_toObject(blockA, blockB); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_TypeError, "FATAL: implementation error, illegal link method"); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* unlinking currently disabled, but might me needed later
 | 
					
						
							|  |  |  |    for other object types... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char DataBlock_unlink_doc[]= | 
					
						
							|  |  |  | "(object) - unlinks 'self' from the specified object.\n\
 | 
					
						
							|  |  |  | See documentation for link() for valid object types."; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject *DataBlock_unlink(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	DataBlock *blockA= (DataBlock*) self; | 
					
						
							|  |  |  | 	DataBlock *blockB; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &blockB)); | 
					
						
							|  |  |  | 	switch (DataBlock_type(blockA)) { | 
					
						
							|  |  |  | 		case ID_SCE: | 
					
						
							|  |  |  | 			switch(DataBlock_type(blockB)) { | 
					
						
							|  |  |  | 				case ID_OB: | 
					
						
							|  |  |  | 					return unlink_Object_fromScene(blockA, blockB); | 
					
						
							|  |  |  | 				default: | 
					
						
							|  |  |  | 					PyErr_SetString(PyExc_TypeError, "Scene unlink: invalid Object type"); | 
					
						
							|  |  |  | 					return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_TypeError, "cannot unlink: invalid object type"); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** These are the methods common to each datablock */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef commonDataBlock_methods[] = { | 
					
						
							|  |  |  | 	{"link", DataBlock_link, METH_VARARGS, DataBlock_link_doc}, | 
					
						
							|  |  |  | //	{"unlink", DataBlock_unlink, METH_VARARGS, DataBlock_unlink_doc},
 | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *DataBlock_getattr(PyObject *self, char *name) { | 
					
						
							|  |  |  | 	DataBlock *block= (DataBlock*) self; | 
					
						
							|  |  |  | 	PyObject *ret = NULL; | 
					
						
							|  |  |  | 	CHECK_VALIDDATA(block, "block was deleted!") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check for common attributes: 
 | 
					
						
							|  |  |  | 	if (STREQ(name, "name")) | 
					
						
							|  |  |  | 		return PyString_FromString((((ID*)block->data)->name)+2); | 
					
						
							|  |  |  | 	else if (STREQ(name, "block_type")) | 
					
						
							|  |  |  | 		return PyString_FromString(block->type); | 
					
						
							|  |  |  | 	else if (STREQ(name, "users")) | 
					
						
							|  |  |  | 		return PyInt_FromLong(((ID*)block->data)->us); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// the following datablock types have methods:
 | 
					
						
							|  |  |  | 	switch (DataBlock_type(block)) { | 
					
						
							|  |  |  | 	case ID_OB: | 
					
						
							|  |  |  | 		ret = Py_FindMethod(Object_methods, self, name); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ID_IP: | 
					
						
							|  |  |  | 		ret = Py_FindMethod(Ipo_methods, self, name); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ID_CA: | 
					
						
							|  |  |  | 		ret = Py_FindMethod(Camera_methods, self, name); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ID_MA: | 
					
						
							|  |  |  | 		ret = Py_FindMethod(Material_methods, self, name); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ID_LA: | 
					
						
							|  |  |  | 		ret = Py_FindMethod(Lamp_methods, self, name); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ID_TXT: | 
					
						
							|  |  |  | 		ret = Py_FindMethod(Text_methods, self, name); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	}	 | 
					
						
							|  |  |  | 	if (ret) return ret; | 
					
						
							|  |  |  | 	PyErr_Clear(); // no method found, clear error
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// try common datablock methods
 | 
					
						
							|  |  |  | 	ret = Py_FindMethod(commonDataBlock_methods, (PyObject*)self, name); | 
					
						
							|  |  |  | 	if (ret) return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// try attributes from property list
 | 
					
						
							|  |  |  | 	ret = datablock_getattr(block->properties, block->type, name, block->data); | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int DataBlock_setattr(PyObject *self, char *name, PyObject *ob) { | 
					
						
							|  |  |  | 	DataBlock *block= (DataBlock*) self; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CHECK_VALIDDATA(block, "block was deleted!") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (STREQ(name, "name")) { | 
					
						
							|  |  |  | 		if (!PyArg_Parse(ob, "s", &name)) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		new_id(block->type_list, (ID*)block->data, name); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return datablock_setattr(block->properties, block->type, name, block->data, ob); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyTypeObject DataBlock_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | 	0,									/*ob_size*/ | 
					
						
							|  |  |  | 	"Block",							/*tp_name*/ | 
					
						
							|  |  |  | 	sizeof(DataBlock),					/*tp_basicsize*/ | 
					
						
							|  |  |  | 	0,									/*tp_itemsize*/ | 
					
						
							|  |  |  | 	(destructor)	DataBlock_dealloc,	/*tp_dealloc*/ | 
					
						
							|  |  |  | 	(printfunc)		0,		/*tp_print*/ | 
					
						
							|  |  |  | 	(getattrfunc)	DataBlock_getattr,	/*tp_getattr*/ | 
					
						
							|  |  |  | 	(setattrfunc)	DataBlock_setattr,	/*tp_setattr*/ | 
					
						
							|  |  |  | 	(cmpfunc) 0,	/*tp_compare*/ | 
					
						
							|  |  |  | 	(reprfunc)      DataBlock_repr,		/*tp_repr*/ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**********************/ | 
					
						
							|  |  |  | /* Texture Datablocks */ | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | DATABLOCK_GET(Texturemodule, texture, getTextureList()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef Texture_methods[] = { | 
					
						
							|  |  |  | 	{"Get", Texture_Get, 1, Texture_Get_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ---------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int DataBlock_type(DataBlock *block) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (GET_ID_TYPE((ID *) block->data)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ObjectDataIDType(DataBlock *block) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *ob; | 
					
						
							|  |  |  | 	if (!DataBlock_isType(block, ID_OB)) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ob = (Object *) block->data; | 
					
						
							|  |  |  | 	return GET_ID_TYPE((ID *) ob->data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int DataBlock_isType(DataBlock *block, int type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ID *id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!DataBlock_Check(block)) return 0; | 
					
						
							|  |  |  | 	id= (ID *) block->data; | 
					
						
							|  |  |  | 	return (GET_ID_TYPE(id))==type; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** This function creates a Python datablock descriptor object from
 | 
					
						
							|  |  |  |   * the specified data pointer. This pointer must point to a structure | 
					
						
							|  |  |  |   * with a valid ID header. | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *DataBlock_fromData(void *data) { | 
					
						
							|  |  |  | 	DataBlock *newb; | 
					
						
							|  |  |  | 	ID *id= (ID *) data; | 
					
						
							|  |  |  | 	int idn; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (!data) return BPY_incr_ret(Py_None); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	idn = GET_ID_TYPE(id); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (idn==ID_OB) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Object"; | 
					
						
							|  |  |  | 		newb->type_list= getObjectList(); | 
					
						
							|  |  |  | 		newb->properties= Object_Properties; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (idn==ID_ME) { | 
					
						
							|  |  |  | #ifdef USE_NMESH	
 | 
					
						
							|  |  |  | 		return newNMesh(data); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Mesh"; | 
					
						
							|  |  |  | 		newb->type_list= getMeshList(); | 
					
						
							|  |  |  | 		newb->properties= Mesh_Properties; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //	} else if (idn==ID_CU) {
 | 
					
						
							|  |  |  | 		/* Special case, should be fixed
 | 
					
						
							|  |  |  | 		 * by proper high-level NURBS access. | 
					
						
							|  |  |  | 		 *  | 
					
						
							|  |  |  | 		 * Later. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		  | 
					
						
							|  |  |  | //		return newNCurveObject(data);			
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (idn==ID_LA) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Lamp"; | 
					
						
							|  |  |  | 		newb->type_list= getLampList(); | 
					
						
							|  |  |  | 		newb->properties= Lamp_Properties; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (idn==ID_CA) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Camera"; | 
					
						
							|  |  |  | 		newb->type_list= getCameraList(); | 
					
						
							|  |  |  | 		newb->properties= Camera_Properties; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (idn==ID_MA) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Material"; | 
					
						
							|  |  |  | 		newb->type_list= getMaterialList(); | 
					
						
							|  |  |  | 		newb->properties= Material_Properties; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	} else if (idn==ID_WO) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "World"; | 
					
						
							|  |  |  | 		newb->type_list= getWorldList(); | 
					
						
							|  |  |  | 		newb->properties= World_Properties; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (idn==ID_IP) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Ipo"; | 
					
						
							|  |  |  | 		newb->type_list= getIpoList(); | 
					
						
							|  |  |  | 		newb->properties= Ipo_Properties;		 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef EXPERIMENTAL
 | 
					
						
							|  |  |  | 	} else if (idn==ID_TE) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Tex"; | 
					
						
							|  |  |  | 		newb->type_list= getTextureList(); | 
					
						
							|  |  |  | 		newb->properties= Texture_Properties;		 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (idn==ID_IM) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Image"; | 
					
						
							|  |  |  | 		newb->type_list= getImageList(); | 
					
						
							|  |  |  | 		newb->properties= Image_Properties;		 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (idn==ID_TXT) { | 
					
						
							|  |  |  | 		newb= PyObject_NEW(DataBlock, &DataBlock_Type); | 
					
						
							|  |  |  | 		newb->type= "Text"; | 
					
						
							|  |  |  | 		newb->type_list= getTextList(); | 
					
						
							|  |  |  | 		newb->properties= Text_Properties;		 | 
					
						
							|  |  |  | 	} else return BPY_err_ret_ob(PyExc_SystemError, "unable to create Block for data"); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	newb->data= data; | 
					
						
							|  |  |  | #ifdef REF_USERCOUNT
 | 
					
						
							|  |  |  | 	BOB_INCUSER(id); // XXX abuse for refcount
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return (PyObject *) newb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *get_DataBlock_func(void **ptr) { | 
					
						
							|  |  |  | 	ID *id= (ID*) *ptr; | 
					
						
							|  |  |  | 	return DataBlock_fromData(id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ---------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /* INIT ROUTINE */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void init_types(PyObject *dict) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *tmod, *tdict; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tmod= Py_InitModule("Blender.Types", Null_methods); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Types", tmod); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	tdict= PyModule_GetDict(tmod); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "IpoCurve", (PyObject *)&PyIpoCurve_Type); | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "BezTriple", (PyObject *)&PyBezTriple_Type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "ButtonType", (PyObject *)&Button_Type); | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "BufferType", (PyObject *)&Buffer_Type); | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "NMeshType", (PyObject *)&NMesh_Type); | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "NMFaceType", (PyObject *)&NMFace_Type); | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "NMVertType", (PyObject *)&NMVert_Type); | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "NMColType", (PyObject *)&NMCol_Type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "BlockType", (PyObject *)&DataBlock_Type); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Setup external types */ | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "VectorType", (PyObject *)&Vector_Type); | 
					
						
							|  |  |  | 	PyDict_SetItemString(tdict, "MatrixType", (PyObject *)&Matrix_Type); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef BPY_ADDCONST
 | 
					
						
							|  |  |  | #define BPY_ADDCONST(dict, name) insertConst(dict, #name, PyInt_FromLong(LA_##name))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *initLamp(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *mod, *dict, *d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Lamp", Lampmodule_methods); | 
					
						
							|  |  |  | 	dict= PyModule_GetDict(mod); | 
					
						
							|  |  |  | 	d = ConstObject_New(); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Types", d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* type */ | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, LOCAL); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SUN); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SPOT); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, HEMI); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	d = ConstObject_New(); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Modes", d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* mode */ | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SHAD); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, HALO); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, LAYER); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, QUAD); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, NEG); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, ONLYSHADOW); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SPHERE); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SQUARE); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, TEXTURE); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, OSATEX); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, DEEP_SHADOW); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return mod; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *initMaterial(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *mod, *dict, *d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Material",  | 
					
						
							|  |  |  | 	                   Materialmodule_methods); | 
					
						
							|  |  |  | 	dict= PyModule_GetDict(mod); | 
					
						
							|  |  |  | 	d = ConstObject_New(); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Modes", d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* MATERIAL MODES 
 | 
					
						
							|  |  |  | 	 * ...some of these have really cryptic defines :-)  | 
					
						
							|  |  |  | 	 * We try to match them to the GUI descriptions...  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef BPY_ADDCONST
 | 
					
						
							|  |  |  | #define BPY_ADDCONST(dict, name) \
 | 
					
						
							|  |  |  | 	insertConst(dict, #name, PyInt_FromLong(MA_##name)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	insertConst(d, "TRACEABLE", PyInt_FromLong(MA_TRACEBLE)); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SHADOW); | 
					
						
							|  |  |  | 	insertConst(d, "SHADELESS", PyInt_FromLong(MA_SHLESS)); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, WIRE); | 
					
						
							|  |  |  | 	insertConst(d, "VCOL_LIGHT", PyInt_FromLong(MA_VERTEXCOL)); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, HALO); | 
					
						
							|  |  |  | 	insertConst(d, "ZTRANSP", PyInt_FromLong(MA_ZTRA)); | 
					
						
							|  |  |  | 	insertConst(d, "VCOL_PAINT", PyInt_FromLong(MA_VERTEXCOLP)); | 
					
						
							|  |  |  | 	insertConst(d, "ZINVERT", PyInt_FromLong(MA_ZINV)); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, ONLYSHADOW); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, STAR); | 
					
						
							|  |  |  | 	insertConst(d, "TEXFACE", PyInt_FromLong(MA_FACETEXTURE)); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, NOMIST); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* HALO MODES */ | 
					
						
							|  |  |  | 	d = ConstObject_New(); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "HaloModes", d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef BPY_ADDCONST
 | 
					
						
							|  |  |  | #define BPY_ADDCONST(dict, name) \
 | 
					
						
							|  |  |  | 	insertConst(dict, #name, PyInt_FromLong(MA_HALO_##name)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, RINGS); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, LINES); | 
					
						
							|  |  |  | 	insertConst(d, "TEX", PyInt_FromLong(MA_HALOTEX)); | 
					
						
							|  |  |  | 	insertConst(d, "PUNO", PyInt_FromLong(MA_HALOPUNO)); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, SHADE); | 
					
						
							|  |  |  | 	BPY_ADDCONST(d, FLARE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return mod; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void init_Datablockmodules(PyObject *dict) { | 
					
						
							|  |  |  | #define MODLOAD(name)	PyDict_SetItemString(dict, #name, Py_InitModule(MODNAME(BLENDERMODULE) "." #name, name##module_methods))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DataBlock_Type.ob_type = &PyType_Type; | 
					
						
							|  |  |  | 	PyIpoCurve_Type.ob_type= &PyType_Type; | 
					
						
							|  |  |  | 	PyBezTriple_Type.ob_type= &PyType_Type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Object", initObject()); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Lamp", initLamp()); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Material", initMaterial()); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Ipo", initIpo()); | 
					
						
							|  |  |  | 	PyDict_SetItemString(dict, "Scene", initScene()); | 
					
						
							|  |  |  | 	MODLOAD(Text); | 
					
						
							|  |  |  | //	MODLOAD(Mesh);
 | 
					
						
							|  |  |  | 	MODLOAD(Camera); | 
					
						
							|  |  |  | 	MODLOAD(World); | 
					
						
							|  |  |  | 	MODLOAD(Image); | 
					
						
							|  |  |  | /* 	MODLOAD(Texture); */ | 
					
						
							|  |  |  | } |