Python API
---------- Support for new bpy.libraries module, which is being proposed to replace the Blender.Library module.
This commit is contained in:
		| @@ -159,6 +159,7 @@ void BPY_start_python( int argc, char **argv ) | ||||
| 	static int argc_copy = 0; | ||||
| 	static char **argv_copy = NULL; | ||||
| 	int first_time = argc; | ||||
| 	char *str, version[16]; | ||||
|  | ||||
| 	/* we keep a copy of the values of argc and argv so that the game engine | ||||
| 	 * can call BPY_start_python(0, NULL) whenever a game ends, without having | ||||
| @@ -178,8 +179,8 @@ void BPY_start_python( int argc, char **argv ) | ||||
| 	 * print an error if not found.  See init_syspath() for the | ||||
| 	 * rest of our init msgs. | ||||
| 	 */ | ||||
| 	// Py_GetVersion() returns a ptr to astatic string | ||||
| 	printf( "Compiled with Python version %.5s.\n", Py_GetVersion() ); | ||||
|  | ||||
| 	printf( "Compiled with Python version %s.\n", PY_VERSION ); | ||||
|  | ||||
| 	//Initialize the TOP-LEVEL modules | ||||
| 	PyImport_ExtendInittab(BPy_Inittab_Modules); | ||||
|   | ||||
| @@ -964,7 +964,7 @@ void M_Blender_Init(void) | ||||
| 	PyDict_SetItemString(dict, "Key", Key_Init()); | ||||
| 	PyDict_SetItemString(dict, "Lamp", Lamp_Init()); | ||||
| 	PyDict_SetItemString(dict, "Lattice", Lattice_Init()); | ||||
| 	PyDict_SetItemString(dict, "Library", Library_Init()); | ||||
| 	PyDict_SetItemString(dict, "Library", oldLibrary_Init()); | ||||
| 	PyDict_SetItemString(dict, "Material", Material_Init()); | ||||
| 	PyDict_SetItemString(dict, "Mesh", Mesh_Init());  | ||||
| 	PyDict_SetItemString(dict, "Metaball", Metaball_Init()); | ||||
|   | ||||
| @@ -28,11 +28,15 @@ | ||||
|  * | ||||
|  * This is a new part of Blender. | ||||
|  * | ||||
|  * Contributor(s): Willian P. Germano | ||||
|  * Contributor(s): Willian P. Germano, Campbell Barton, Ken Hughes | ||||
|  * | ||||
|  * ***** END GPL/BL DUAL LICENSE BLOCK ***** | ||||
| */ | ||||
|  | ||||
| /************************************************************/ | ||||
| /* Original library module code                             */ | ||||
| /************************************************************/ | ||||
|  | ||||
| #include <Python.h> | ||||
|  | ||||
| #include "DNA_curve_types.h" | ||||
| @@ -64,14 +68,13 @@ static PyObject *M_Library_Close( PyObject * self ); | ||||
| static PyObject *M_Library_GetName( PyObject * self ); | ||||
| static PyObject *M_Library_Update( PyObject * self ); | ||||
| static PyObject *M_Library_Datablocks( PyObject * self, PyObject * args ); | ||||
| static PyObject *M_Library_Load( PyObject * self, PyObject * args ); | ||||
| static PyObject *oldM_Library_Load( PyObject * self, PyObject * args ); | ||||
| static PyObject *M_Library_LinkableGroups( PyObject * self ); | ||||
| static PyObject *M_Library_LinkedLibs( PyObject * self ); | ||||
|  | ||||
| PyObject *Library_Init( void ); | ||||
| void EXPP_Library_Close( void ); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Module doc strings. | ||||
|  */ | ||||
| @@ -119,7 +122,7 @@ static char Library_LinkedLibs_doc[] = | ||||
| /** | ||||
|  * Python method structure definition for Blender.Library submodule. | ||||
|  */ | ||||
| struct PyMethodDef M_Library_methods[] = { | ||||
| struct PyMethodDef oldM_Library_methods[] = { | ||||
| 	{"Open", M_Library_Open, METH_VARARGS, Library_Open_doc}, | ||||
| 	{"Close", ( PyCFunction ) M_Library_Close, METH_NOARGS, | ||||
| 	 Library_Close_doc}, | ||||
| @@ -129,7 +132,7 @@ struct PyMethodDef M_Library_methods[] = { | ||||
| 	 Library_Update_doc}, | ||||
| 	{"Datablocks", M_Library_Datablocks, METH_VARARGS, | ||||
| 	 Library_Datablocks_doc}, | ||||
| 	{"Load", M_Library_Load, METH_VARARGS, Library_Load_doc}, | ||||
| 	{"Load", oldM_Library_Load, METH_VARARGS, Library_Load_doc}, | ||||
| 	{"LinkableGroups", ( PyCFunction ) M_Library_LinkableGroups, | ||||
| 	 METH_NOARGS, Library_LinkableGroups_doc}, | ||||
| 	{"LinkedLibs", ( PyCFunction ) M_Library_LinkedLibs, | ||||
| @@ -144,7 +147,7 @@ struct PyMethodDef M_Library_methods[] = { | ||||
|  * Only one can be open at a time, so this function also closes | ||||
|  * the previously opened file, if any. | ||||
|  */ | ||||
| PyObject *M_Library_Open( PyObject * self, PyObject * args ) | ||||
| static PyObject *M_Library_Open( PyObject * self, PyObject * args ) | ||||
| { | ||||
| 	char *fname = NULL; | ||||
| 	char filename[FILE_MAXDIR+FILE_MAXFILE]; | ||||
| @@ -193,7 +196,7 @@ PyObject *M_Library_Open( PyObject * self, PyObject * args ) | ||||
| /** | ||||
|  * Close the current .blend file, if any. | ||||
|  */ | ||||
| PyObject *M_Library_Close( PyObject * self ) | ||||
| static PyObject *M_Library_Close( PyObject * self ) | ||||
| { | ||||
| 	if( bpy_openlib ) { | ||||
| 		BLO_blendhandle_close( bpy_openlib ); | ||||
| @@ -228,7 +231,7 @@ void EXPP_Library_Close( void ) | ||||
| /** | ||||
|  * Get the filename of the currently open library file, if any. | ||||
|  */ | ||||
| PyObject *M_Library_GetName( PyObject * self ) | ||||
| static PyObject *M_Library_GetName( PyObject * self ) | ||||
| { | ||||
| 	if( bpy_openlib && bpy_openlibname ) | ||||
| 		return Py_BuildValue( "s", bpy_openlibname ); | ||||
| @@ -241,7 +244,7 @@ PyObject *M_Library_GetName( PyObject * self ) | ||||
|  * Return a list with all items of a given datablock type | ||||
|  * (like 'Object', 'Mesh', etc.) in the open library file. | ||||
|  */ | ||||
| PyObject *M_Library_Datablocks( PyObject * self, PyObject * args ) | ||||
| static PyObject *M_Library_Datablocks( PyObject * self, PyObject * args ) | ||||
| { | ||||
| 	char *name = NULL; | ||||
| 	int blocktype = 0; | ||||
| @@ -288,7 +291,7 @@ PyObject *M_Library_Datablocks( PyObject * self, PyObject * args ) | ||||
|  * Return a list with the names of all linkable groups in the | ||||
|  * open library file. | ||||
|  */ | ||||
| PyObject *M_Library_LinkableGroups( PyObject * self ) | ||||
| static PyObject *M_Library_LinkableGroups( PyObject * self ) | ||||
| { | ||||
| 	LinkNode *l = NULL, *names = NULL; | ||||
| 	PyObject *list = NULL; | ||||
| @@ -317,7 +320,7 @@ PyObject *M_Library_LinkableGroups( PyObject * self ) | ||||
| /** | ||||
|  * Return a list with the names of all externally linked libs used in the current Blend file | ||||
|  */ | ||||
| PyObject *M_Library_LinkedLibs( PyObject * self ) | ||||
| static PyObject *M_Library_LinkedLibs( PyObject * self ) | ||||
| { | ||||
| 	int counter = 0; | ||||
| 	Library *li; | ||||
| @@ -335,7 +338,7 @@ PyObject *M_Library_LinkedLibs( PyObject * self ) | ||||
|  * Load (append) a given datablock of a given datablock type | ||||
|  * to the current scene. | ||||
|  */ | ||||
| PyObject *M_Library_Load( PyObject * self, PyObject * args ) | ||||
| static PyObject *oldM_Library_Load( PyObject * self, PyObject * args ) | ||||
| { | ||||
| 	char *name = NULL; | ||||
| 	char *base = NULL; | ||||
| @@ -360,9 +363,9 @@ PyObject *M_Library_Load( PyObject * self, PyObject * args ) | ||||
| 					      "no such Blender datablock type" ); | ||||
| 	 | ||||
| 	if (linked) | ||||
| 		BLO_script_library_append( bpy_openlib, bpy_openlibname, name, blocktype, FILE_LINK); | ||||
| 		BLO_script_library_append( bpy_openlib, bpy_openlibname, name, blocktype, FILE_LINK, G.scene); | ||||
| 	else | ||||
| 		BLO_script_library_append( bpy_openlib, bpy_openlibname, name, blocktype, 0); | ||||
| 		BLO_script_library_append( bpy_openlib, bpy_openlibname, name, blocktype, 0, G.scene); | ||||
| 	 | ||||
| 	if( update ) { | ||||
| 		M_Library_Update( self ); | ||||
| @@ -394,7 +397,7 @@ PyObject *M_Library_Load( PyObject * self, PyObject * args ) | ||||
| /** | ||||
|  * Update all links and remake displists. | ||||
|  */ | ||||
| PyObject *M_Library_Update( PyObject * self ) | ||||
| static PyObject *M_Library_Update( PyObject * self ) | ||||
| {				/* code adapted from do_library_append in src/filesel.c: */ | ||||
| 	Library *lib = NULL; | ||||
|  | ||||
| @@ -425,12 +428,751 @@ PyObject *M_Library_Update( PyObject * self ) | ||||
|  * Called by Blender_Init in Blender.c . | ||||
|  * @return the registered submodule. | ||||
|  */ | ||||
| PyObject *Library_Init( void ) | ||||
| PyObject *oldLibrary_Init( void ) | ||||
| { | ||||
| 	PyObject *submod; | ||||
|  | ||||
| 	submod = Py_InitModule3( "Blender.Library", M_Library_methods, | ||||
| 	submod = Py_InitModule3( "Blender.Library", oldM_Library_methods, | ||||
| 				 M_Library_doc ); | ||||
|  | ||||
| 	return submod; | ||||
| } | ||||
|  | ||||
| /************************************************************/ | ||||
| /* New library (LibData) module code                        */ | ||||
| /************************************************************/ | ||||
|  | ||||
| #include "Library.h" | ||||
|  | ||||
| /* if this module supercedes the old library module, include these instead */ | ||||
| #if 0 | ||||
| #include "BLI_blenlib.h" | ||||
| #include "MEM_guardedalloc.h" | ||||
|  | ||||
| #include "DNA_curve_types.h" | ||||
| #include "DNA_object_types.h" | ||||
| #include "DNA_space_types.h" /* for line linked */ | ||||
| #include "BKE_library.h"	/* for all_local */ | ||||
| #include "BKE_utildefines.h" | ||||
| #include "BKE_global.h" | ||||
| #include "BKE_main.h" | ||||
| #include "BLO_readfile.h" | ||||
| #include "BLI_linklist.h" | ||||
|  | ||||
| #include "Object.h" | ||||
| #include "gen_utils.h" | ||||
| #endif | ||||
|  | ||||
| #include "gen_library.h" | ||||
|  | ||||
| /* Helper function */ | ||||
|  | ||||
| /* | ||||
|  * Try to open a library, set Python exceptions as necessary if not | ||||
|  * successful.  On success, return a valid handle; othewise return NULL. | ||||
|  */ | ||||
|  | ||||
| static BlendHandle *open_library( char *filename, char *longFilename ) | ||||
| { | ||||
| 	char globalFilename[FILE_MAX]; | ||||
| 	BlendHandle *openlib = NULL; | ||||
|  | ||||
| 	/* get complete file name if necessary */ | ||||
| 	BLI_strncpy( longFilename, filename, FILE_MAX );  | ||||
| 	BLI_convertstringcode( longFilename, G.sce, 0 ); | ||||
|  | ||||
| 	/* throw exceptions for wrong file type, cyclic reference */ | ||||
| 	if( !BLO_has_bfile_extension(longFilename) ) { | ||||
| 		PyErr_SetString( PyExc_ValueError, "file not a library" ); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	if( BLI_streq(G.main->name, longFilename) ) { | ||||
| 		PyErr_SetString( PyExc_ValueError, | ||||
| 				"cannot use current file as library" ); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
|    	/* G.sce = last file loaded, save for UI and restore after opening file */ | ||||
| 	BLI_strncpy(globalFilename, G.sce, sizeof(globalFilename)); | ||||
| 	openlib = BLO_blendhandle_from_file( longFilename ); | ||||
| 	BLI_strncpy(G.sce, globalFilename, sizeof(globalFilename));  | ||||
|  | ||||
| 	/* if failed, set that exception code too */ | ||||
| 	if( !openlib ) | ||||
| 		PyErr_SetString( PyExc_IOError, "library not found" ); | ||||
|  | ||||
| 	return openlib; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Create a specific type of LibraryData object.  These are used for | ||||
|  * .append() and .link() access, for iterators, and (for Blender Objects) | ||||
|  * for defining "pseudo objects" for scene linking. | ||||
|  */ | ||||
|  | ||||
| static PyObject *CreatePyObject_LibData( int idtype, int kind, | ||||
| 		void *name, void *iter, char *filename ) | ||||
| { | ||||
| 	BPy_LibraryData *seq = PyObject_NEW( BPy_LibraryData, &LibraryData_Type); | ||||
| 	seq->iter = iter;		/* the name list (for iterators) */ | ||||
| 	seq->type = idtype;		/* the Blender ID type */ | ||||
| 	seq->kind = kind;		/* used by Blender Objects */ | ||||
| 	seq->name = name; 		/* object name, iterator name list, or NULL */ | ||||
| 							/* save the library name */ | ||||
| 	BLI_strncpy( seq->filename, filename, strlen(filename)+1 ); | ||||
| 	return (PyObject *)seq; | ||||
| } | ||||
|  | ||||
| /*  | ||||
|  * Link/append data to the current .blend file, or create a pseudo object | ||||
|  * which can be linked/appended to a scene. | ||||
|  */ | ||||
|  | ||||
| static PyObject *lib_link_or_append( BPy_LibraryData *self, PyObject * args, | ||||
| 		int mode ) | ||||
| { | ||||
| 	char *name; | ||||
|  | ||||
| 	/* get the name of the data used wants to append */ | ||||
| 	if( !PyArg_ParseTuple( args, "s", &name ) ) | ||||
| 		return EXPP_ReturnPyObjError( PyExc_TypeError, | ||||
| 			"expected a string" ); | ||||
|  | ||||
| 	/*  | ||||
| 	 * For everything except objects, just add to Blender's DB.  For objects, | ||||
| 	 * create an APPEND or LINK "pseudo object" for the Scene module. | ||||
| 	 */ | ||||
| 	if( self->type != ID_OB ) | ||||
| 		return LibraryData_importLibData( self, name, 0, NULL ); | ||||
| 	else { | ||||
| 		/* | ||||
| 		 * If this is already a pseudo object, throw an exception: re-linking | ||||
| 		 * or re-appending is not allowed | ||||
| 		 */ | ||||
| 		if( self->kind != OTHER )  | ||||
| 			return EXPP_ReturnPyObjError( PyExc_ValueError, | ||||
| 				"object has already been marked for append or link" ); | ||||
|  | ||||
| 		/* otherwise, create a pseudo object ready for appending or linking */ | ||||
|  | ||||
| 		return CreatePyObject_LibData( ID_OB, mode,  | ||||
| 				BLI_strdupn( name, strlen( name ) ), NULL, self->filename ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Perform the actual link or append operation.  This procedure is also | ||||
|  * called externally from the Scene module using a "pseudo Object" so we | ||||
|  * can be sure objects get linked to a scene. | ||||
|  */ | ||||
|  | ||||
| PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name, | ||||
| 		int mode, Scene *scene ) | ||||
| { | ||||
| 	char longFilename[FILE_MAX]; | ||||
| 	char *finalName; | ||||
| 	BlendHandle *openlib; | ||||
| 	Library *lib; | ||||
| 	LinkNode *names, *ptr; | ||||
| 	ID idtest, *id; | ||||
| 	ListBase *lb; | ||||
|  | ||||
| 	/* try to open the library */ | ||||
| 	openlib = open_library( self->filename, longFilename ); | ||||
| 	if( !openlib ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	/* find all datablocks for the specified type */ | ||||
| 	names = BLO_blendhandle_get_datablock_names ( openlib, self->type );  | ||||
|  | ||||
| 	/* now check for a match to the user-specified name */ | ||||
| 	for( ptr = names; ptr; ptr = ptr->next ) | ||||
| 		if( strcmp( ptr->link, name ) == 0 ) break; | ||||
| 	BLI_linklist_free( names, free ); | ||||
|  | ||||
| 	/* if no match, throw exception */ | ||||
| 	if( !ptr ) { | ||||
| 		BLO_blendhandle_close( openlib ); | ||||
| 		return EXPP_ReturnPyObjError( PyExc_ValueError, | ||||
| 				"library does not contain specified item" ); | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * Figure out what the datablock will be named after it's imported.  If | ||||
| 	 * it's a link, nothing to do.  If it's an append, find what it might | ||||
| 	 * be renamed to. | ||||
| 	 */ | ||||
|  | ||||
| 	if( mode == FILE_LINK ) | ||||
| 		finalName =  name; | ||||
| 	else { /* for appends, build a fake ID block, then try to dup it */ | ||||
| 		strncpy( idtest.name+2, name, strlen(name)+1 ); | ||||
| 		*((short *)&idtest.name) = self->type; | ||||
| 		idtest.newid = NULL; | ||||
| 		idtest.lib = NULL; | ||||
| 		dup_id( NULL, &idtest, self->name ); | ||||
| 		finalName = idtest.name+2; | ||||
| 	} | ||||
|  | ||||
| 	/* import from the libary */ | ||||
| 	BLO_script_library_append( openlib, longFilename, name, self->type, mode, | ||||
| 			scene ); | ||||
|  | ||||
| 	/* | ||||
| 	 * locate the library.  If this is an append, make the data local.  If it | ||||
| 	 * is link, we need the library for later | ||||
| 	 */ | ||||
| 	for( lib = G.main->library.first; lib; lib = lib->id.next ) | ||||
| 		if( strcmp( longFilename, lib->name ) == 0 ) { | ||||
| 			if( mode != FILE_LINK ) { | ||||
| 				all_local( lib ); | ||||
| 				lib = NULL; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 	/* done with library; close it */ | ||||
| 	BLO_blendhandle_close( openlib ); | ||||
|  | ||||
| 	/* find the base for this type */ | ||||
| 	lb = wich_libbase( G.main, self->type ); | ||||
|  | ||||
| 	/* | ||||
| 	 * Search the base for the datablock.  For link, lib points to library, | ||||
| 	 * otherwise it's NULL.  | ||||
| 	 */ | ||||
| 	for( id = lb->first; id; id = id->next ) { | ||||
| 		if( id->lib == lib && id->name[2]==finalName[0] && | ||||
| 				strcmp(id->name+2, finalName)==0 ) | ||||
| 			return GetPyObjectFromID( id ); | ||||
| 	} | ||||
|  | ||||
| 	/* if we get here, something's really wrong */ | ||||
| 	return EXPP_ReturnPyObjError( PyExc_RuntimeError, | ||||
| 			"could not find data after reading from library" ); | ||||
| } | ||||
|  | ||||
| /************************************************************ | ||||
|  * Python LibraryData_Type getseters | ||||
|  ************************************************************/ | ||||
|  | ||||
| /* .append(): make a local copy of the library's data (except for objects) */ | ||||
|  | ||||
| static PyObject *LibraryData_getAppend( BPy_LibraryData *self, PyObject * args) | ||||
| { | ||||
| 	return lib_link_or_append( self, args, OBJECT_IS_APPEND ); | ||||
| } | ||||
|  | ||||
| /* .link(): make a link to the library's data (except for objects) */ | ||||
|  | ||||
| static PyObject *LibraryData_getLink( BPy_LibraryData *self, PyObject * args) | ||||
| { | ||||
| 	return lib_link_or_append( self, args, OBJECT_IS_LINK ); | ||||
| } | ||||
|  | ||||
| /************************************************************************ | ||||
|  * Python LibraryData_Type iterator | ||||
|  ************************************************************************/ | ||||
|  | ||||
| /* Create and initialize the interator indices */ | ||||
|  | ||||
| static PyObject *LibraryData_getIter( BPy_LibraryData * self ) | ||||
| { | ||||
| 	char longFilename[FILE_MAX]; | ||||
| 	BlendHandle *openlib; | ||||
| 	LinkNode *names; | ||||
|  | ||||
| 	/* try to open library */ | ||||
| 	openlib = open_library( self->filename, longFilename ); | ||||
|  | ||||
| 	/* if failed, return exception */ | ||||
| 	if( !openlib ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	/* find all datablocks for the specified type */ | ||||
| 	names = BLO_blendhandle_get_datablock_names ( openlib, self->type );  | ||||
|  | ||||
| 	/* close library*/ | ||||
| 	BLO_blendhandle_close( openlib ); | ||||
|  | ||||
| 	/* build an iterator object for the name list */ | ||||
| 	return CreatePyObject_LibData( self->type, OTHER, names, | ||||
| 			names, self->filename ); | ||||
| } | ||||
|  | ||||
| /* Return next name. */ | ||||
|  | ||||
| static PyObject *LibraryData_nextIter( BPy_LibraryData * self ) | ||||
| { | ||||
| 	LinkNode *ptr = (LinkNode *)self->iter; | ||||
| 	PyObject *ob; | ||||
|  | ||||
| 	/* if at the end of list, clean up */ | ||||
| 	if( !ptr ) { | ||||
| 		/* If name list is still allocated, free storage.  This check is | ||||
| 		 * necessary since iter.next() can technically be called repeatedly */ | ||||
| 		if( self->name ) { | ||||
| 			BLI_linklist_free( (LinkNode *)self->name, free ); | ||||
| 			self->name = NULL; | ||||
| 		} | ||||
| 		return EXPP_ReturnPyObjError( PyExc_StopIteration, | ||||
| 				"iterator at end" ); | ||||
| 	} | ||||
|  | ||||
| 	/* otherwise, return the next name in the list */ | ||||
| 	ob = PyString_FromString( ptr->link ); | ||||
| 	ptr = ptr->next; | ||||
| 	self->iter = ptr; | ||||
| 	return ob; | ||||
| } | ||||
|  | ||||
| /************************************************************************ | ||||
|  * Python LibraryData_type methods structure | ||||
|  ************************************************************************/ | ||||
|  | ||||
| static struct PyMethodDef BPy_LibraryData_methods[] = { | ||||
| 	{"append", (PyCFunction)LibraryData_getAppend, METH_VARARGS, | ||||
| 	 "(str) - create new data from library"}, | ||||
| 	{"link", (PyCFunction)LibraryData_getLink, METH_VARARGS, | ||||
| 	 "(str) - link data from library"}, | ||||
| 	{NULL, NULL, 0, NULL} | ||||
| }; | ||||
|  | ||||
| /* Deallocate object and its data */ | ||||
|  | ||||
| static void LibraryData_dealloc( BPy_LibraryData * self ) | ||||
| { | ||||
| 	if( self->name ) | ||||
| 		MEM_freeN( self->name ); | ||||
|  | ||||
| 	PyObject_DEL( self ); | ||||
| } | ||||
|  | ||||
| /* Display representation of what Library Data is wrapping */ | ||||
|  | ||||
| static PyObject *LibraryData_repr( BPy_LibraryData * self ) | ||||
| { | ||||
| 	char *linkstate = ""; | ||||
| 	char *str; | ||||
|  | ||||
| 	switch (self->type) { | ||||
| 	case ID_OB: | ||||
| 		/* objects can be lib data or pseudo objects */ | ||||
| 		switch( self->kind ) { | ||||
| 		case OBJECT_IS_APPEND : | ||||
| 			linkstate = ", appended"; | ||||
| 			break; | ||||
| 		case OBJECT_IS_LINK : | ||||
| 			linkstate = ", linked"; | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 		} | ||||
| 		str = "Object"; | ||||
| 		break; | ||||
| 	case ID_SCE: | ||||
| 		str = "Scene"; | ||||
| 		break; | ||||
| 	case ID_ME: | ||||
| 		str = "Mesh"; | ||||
| 		break; | ||||
| 	case ID_CU: | ||||
| 		str = "Curve"; | ||||
| 		break; | ||||
| 	case ID_MB: | ||||
| 		str = "Metaball"; | ||||
| 		break; | ||||
| 	case ID_MA: | ||||
| 		str = "Material"; | ||||
| 		break; | ||||
| 	case ID_TE: | ||||
| 		str = "Texture"; | ||||
| 		break; | ||||
| 	case ID_IM:  | ||||
| 		str = "Image"; | ||||
| 		break; | ||||
| 	case ID_LT: | ||||
| 		str = "Lattice"; | ||||
| 		break; | ||||
| 	case ID_LA: | ||||
| 		str = "Lamp"; | ||||
| 		break; | ||||
| 	case ID_CA: | ||||
| 		str = "Camera"; | ||||
| 		break; | ||||
| 	case ID_IP: | ||||
| 		str = "Ipo"; | ||||
| 		break; | ||||
| 	case ID_WO: | ||||
| 		str = "World"; | ||||
| 		break; | ||||
| 	case ID_VF: | ||||
| 		str = "Font"; | ||||
| 		break; | ||||
| 	case ID_TXT: | ||||
| 		str = "Text"; | ||||
| 		break; | ||||
| 	case ID_SO: | ||||
| 		str = "Sound"; | ||||
| 		break; | ||||
| 	case ID_GR:	 | ||||
| 		str = "Group"; | ||||
| 		break; | ||||
| 	case ID_AR: | ||||
| 		str = "Armature"; | ||||
| 		break; | ||||
| 	case ID_AC: | ||||
| 		str = "Action"; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError, | ||||
| 				"unsupported ID type" ); | ||||
| 	} | ||||
|  | ||||
| 	return PyString_FromFormat( "[Library Data (%s%s)]", str, linkstate ); | ||||
| } | ||||
|  | ||||
| PyTypeObject LibraryData_Type = { | ||||
| 	PyObject_HEAD_INIT( NULL )  /* required py macro */ | ||||
| 	0,                          /* ob_size */ | ||||
| 	/*  For printing, in format "<module>.<name>" */ | ||||
| 	"Blender LibData",          /* char *tp_name; */ | ||||
| 	sizeof( BPy_LibraryData ),  /* int tp_basicsize; */ | ||||
| 	0,                          /* tp_itemsize;  For allocation */ | ||||
|  | ||||
| 	/* Methods to implement standard operations */ | ||||
|  | ||||
| 	( destructor ) LibraryData_dealloc,/* destructor tp_dealloc; */ | ||||
| 	NULL,                       /* printfunc tp_print; */ | ||||
| 	NULL,                       /* getattrfunc tp_getattr; */ | ||||
| 	NULL,                       /* setattrfunc tp_setattr; */ | ||||
| 	( cmpfunc ) NULL,           /* cmpfunc tp_compare; */ | ||||
| 	( reprfunc ) LibraryData_repr, /* reprfunc tp_repr; */ | ||||
|  | ||||
| 	/* Method suites for standard classes */ | ||||
|  | ||||
| 	NULL,                       /* PyNumberMethods *tp_as_number; */ | ||||
| 	NULL,	                    /* PySequenceMethods *tp_as_sequence; */ | ||||
| 	NULL,                       /* PyMappingMethods *tp_as_mapping; */ | ||||
|  | ||||
| 	/* More standard operations (here for binary compatibility) */ | ||||
|  | ||||
| 	NULL,                       /* hashfunc tp_hash; */ | ||||
| 	NULL,                       /* ternaryfunc tp_call; */ | ||||
| 	NULL,                       /* reprfunc tp_str; */ | ||||
| 	NULL,                       /* getattrofunc tp_getattro; */ | ||||
| 	NULL,                       /* setattrofunc tp_setattro; */ | ||||
|  | ||||
| 	/* Functions to access object as input/output buffer */ | ||||
| 	NULL,                       /* PyBufferProcs *tp_as_buffer; */ | ||||
|  | ||||
|   /*** Flags to define presence of optional/expanded features ***/ | ||||
| 	Py_TPFLAGS_DEFAULT,         /* long tp_flags; */ | ||||
|  | ||||
| 	NULL,                       /*  char *tp_doc;  Documentation string */ | ||||
|   /*** Assigned meaning in release 2.0 ***/ | ||||
| 	/* call function for all accessible objects */ | ||||
| 	NULL,                       /* traverseproc tp_traverse; */ | ||||
|  | ||||
| 	/* delete references to contained objects */ | ||||
| 	NULL,                       /* inquiry tp_clear; */ | ||||
|  | ||||
|   /***  Assigned meaning in release 2.1 ***/ | ||||
|   /*** rich comparisons ***/ | ||||
| 	NULL,                       /* richcmpfunc tp_richcompare; */ | ||||
|  | ||||
|   /***  weak reference enabler ***/ | ||||
| 	0,                          /* long tp_weaklistoffset; */ | ||||
|  | ||||
|   /*** Added in release 2.2 ***/ | ||||
| 	/*   Iterators */ | ||||
| 	(getiterfunc)LibraryData_getIter, /* getiterfunc tp_iter; */ | ||||
| 	(iternextfunc)LibraryData_nextIter, /* iternextfunc tp_iternext; */ | ||||
|  | ||||
|   /*** Attribute descriptor and subclassing stuff ***/ | ||||
| 	BPy_LibraryData_methods,    /* struct PyMethodDef *tp_methods; */ | ||||
| 	NULL,                       /* struct PyMemberDef *tp_members; */ | ||||
| 	NULL,                       /* struct PyGetSetDef *tp_getset; */ | ||||
| 	NULL,                       /* struct _typeobject *tp_base; */ | ||||
| 	NULL,                       /* PyObject *tp_dict; */ | ||||
| 	NULL,                       /* descrgetfunc tp_descr_get; */ | ||||
| 	NULL,                       /* descrsetfunc tp_descr_set; */ | ||||
| 	0,                          /* long tp_dictoffset; */ | ||||
| 	NULL,                       /* initproc tp_init; */ | ||||
| 	NULL,                       /* allocfunc tp_alloc; */ | ||||
| 	NULL,                       /* newfunc tp_new; */ | ||||
| 	/*  Low-level free-memory routine */ | ||||
| 	NULL,                       /* freefunc tp_free;  */ | ||||
| 	/* For PyObject_IS_GC */ | ||||
| 	NULL,                       /* inquiry tp_is_gc;  */ | ||||
| 	NULL,                       /* PyObject *tp_bases; */ | ||||
| 	/* method resolution order */ | ||||
| 	NULL,                       /* PyObject *tp_mro;  */ | ||||
| 	NULL,                       /* PyObject *tp_cache; */ | ||||
| 	NULL,                       /* PyObject *tp_subclasses; */ | ||||
| 	NULL,                       /* PyObject *tp_weaklist; */ | ||||
| 	NULL | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Create a LibraryData object for a specific type of Blender Group (ID_OB, | ||||
|  * ID_MA, etc).  These can then be used to link or append the data. | ||||
|  */ | ||||
|  | ||||
| static PyObject *LibraryData_CreatePyObject( BPy_Library *self, void *mode ) | ||||
| { | ||||
| 	return CreatePyObject_LibData( (int)mode, OTHER, NULL, NULL, | ||||
| 			self->filename ); | ||||
| } | ||||
|  | ||||
| /************************************************************ | ||||
|  * Python Library_Type getseters | ||||
|  ************************************************************/ | ||||
|  | ||||
| /* | ||||
|  * Return the library's filename. | ||||
|  */ | ||||
|  | ||||
| static PyObject *Library_getFilename( BPy_Library * self ) | ||||
| { | ||||
| 	return PyString_FromString( self->filename ); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Set/change the library's filename. | ||||
|  */ | ||||
|  | ||||
| static int Library_setFilename( BPy_Library * self, PyObject * args ) | ||||
| { | ||||
| 	char *filename = PyString_AsString( args ); | ||||
| 	if( !filename ) | ||||
| 		return EXPP_ReturnIntError( PyExc_TypeError, "expected a string" ); | ||||
|  | ||||
| 	BLI_strncpy( self->filename, filename, sizeof(self->filename) ); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /************************************************************************ | ||||
|  * Python Library_type attributes get/set structure | ||||
|  ************************************************************************/ | ||||
|  | ||||
| static PyGetSetDef Library_getseters[] = { | ||||
| 	{"filename", | ||||
| 	 (getter)Library_getFilename, (setter)Library_setFilename, | ||||
| 	 "library filename", | ||||
| 	 NULL}, | ||||
| 	{"objects", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "objects from the library", | ||||
| 	 (void *)ID_OB}, | ||||
| 	{"scenes", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "scenes from the library", | ||||
| 	 (void *)ID_SCE}, | ||||
| 	{"meshes", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "meshes from the library", | ||||
| 	 (void *)ID_ME}, | ||||
| 	{"curves", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "curves from the library", | ||||
| 	 (void *)ID_CU}, | ||||
| 	{"metaballs", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "metaballs from the library", | ||||
| 	 (void *)ID_MB}, | ||||
| 	{"lattices", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "lattices from the library", | ||||
| 	 (void *)ID_LT}, | ||||
| 	{"lamps", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "lamps from the library", | ||||
| 	 (void *)ID_LA}, | ||||
| 	{"cameras", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "cameras from the library", | ||||
| 	 (void *)ID_CA}, | ||||
| 	{"materials", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "objects from the library", | ||||
| 	 (void *)ID_MA}, | ||||
| 	{"textures", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "textures from the library", | ||||
| 	 (void *)ID_TE}, | ||||
| 	{"images", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "images from the library", | ||||
| 	 (void *)ID_IM}, | ||||
| 	{"ipos", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "ipos from the library", | ||||
| 	 (void *)ID_IP}, | ||||
| 	{"worlds", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "worlds from the library", | ||||
| 	 (void *)ID_WO}, | ||||
| 	{"fonts", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "fonts from the library", | ||||
| 	 (void *)ID_VF}, | ||||
| 	{"texts", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "texts from the library", | ||||
| 	 (void *)ID_TXT}, | ||||
| 	{"groups", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "groups from the library", | ||||
| 	 (void *)ID_GR}, | ||||
| 	{"sounds", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "sounds from the library", | ||||
| 	 (void *)ID_SO}, | ||||
| 	{"actions", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "actions from the library", | ||||
| 	 (void *)ID_AC}, | ||||
| 	{"armatures", | ||||
| 	 (getter)LibraryData_CreatePyObject, (setter)NULL, | ||||
| 	 "armatures from the library", | ||||
| 	 (void *)ID_AR}, | ||||
| 	{NULL,NULL,NULL,NULL,NULL}  /* Sentinel */ | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Define a new library and create a library object.  We don't actually test | ||||
|  * if the library is valid here since we have to do it when the file is | ||||
|  * actually accessed later.  | ||||
|  */ | ||||
|  | ||||
| static PyObject *M_Library_Load(PyObject *self, PyObject * args) | ||||
| { | ||||
| 	char *filename; | ||||
| 	BPy_Library *lib; | ||||
|  | ||||
| 	if( !PyArg_ParseTuple( args, "s", &filename ) ) | ||||
| 		return EXPP_ReturnPyObjError( PyExc_TypeError, | ||||
| 			"expected a string" ); | ||||
|  | ||||
| 	/* try to create a new object */ | ||||
| 	lib = (BPy_Library *)PyObject_NEW( BPy_Library, &Library_Type ); | ||||
| 	if( !lib ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	/* assign the library filename for future use, then return */ | ||||
| 	BLI_strncpy( lib->filename, filename, sizeof(lib->filename) ); | ||||
|  | ||||
| 	return (PyObject *)lib; | ||||
| } | ||||
|  | ||||
| static struct PyMethodDef M_Library_methods[] = { | ||||
| 	{"load", (PyCFunction)M_Library_Load, METH_VARARGS, | ||||
| 	"(string) - declare a .blend file for use as a library"}, | ||||
| 	{NULL, NULL, 0, NULL} | ||||
| }; | ||||
|  | ||||
| /*****************************************************************************/ | ||||
| /* Python Library_Type structure definition:                               */ | ||||
| /*****************************************************************************/ | ||||
| PyTypeObject Library_Type = { | ||||
| 	PyObject_HEAD_INIT( NULL )  /* required py macro */ | ||||
| 	0,                          /* ob_size */ | ||||
| 	/*  For printing, in format "<module>.<name>" */ | ||||
| 	"Blender Library",          /* char *tp_name; */ | ||||
| 	sizeof( BPy_Library ),      /* int tp_basicsize; */ | ||||
| 	0,                          /* tp_itemsize;  For allocation */ | ||||
|  | ||||
| 	/* Methods to implement standard operations */ | ||||
|  | ||||
| 	NULL,                       /* destructor tp_dealloc; */ | ||||
| 	NULL,                       /* printfunc tp_print; */ | ||||
| 	NULL,                       /* getattrfunc tp_getattr; */ | ||||
| 	NULL,                       /* setattrfunc tp_setattr; */ | ||||
| 	( cmpfunc ) NULL,           /* cmpfunc tp_compare; */ | ||||
| 	( reprfunc ) NULL,          /* reprfunc tp_repr; */ | ||||
|  | ||||
| 	/* Method suites for standard classes */ | ||||
|  | ||||
| 	NULL,                       /* PyNumberMethods *tp_as_number; */ | ||||
| 	NULL,	                    /* PySequenceMethods *tp_as_sequence; */ | ||||
| 	NULL,                       /* PyMappingMethods *tp_as_mapping; */ | ||||
|  | ||||
| 	/* More standard operations (here for binary compatibility) */ | ||||
|  | ||||
| 	NULL,                       /* hashfunc tp_hash; */ | ||||
| 	NULL,                       /* ternaryfunc tp_call; */ | ||||
| 	NULL,                       /* reprfunc tp_str; */ | ||||
| 	NULL,                       /* getattrofunc tp_getattro; */ | ||||
| 	NULL,                       /* setattrofunc tp_setattro; */ | ||||
|  | ||||
| 	/* Functions to access object as input/output buffer */ | ||||
| 	NULL,                       /* PyBufferProcs *tp_as_buffer; */ | ||||
|  | ||||
|   /*** Flags to define presence of optional/expanded features ***/ | ||||
| 	Py_TPFLAGS_DEFAULT,         /* long tp_flags; */ | ||||
|  | ||||
| 	NULL,                       /*  char *tp_doc;  Documentation string */ | ||||
|   /*** Assigned meaning in release 2.0 ***/ | ||||
| 	/* call function for all accessible objects */ | ||||
| 	NULL,                       /* traverseproc tp_traverse; */ | ||||
|  | ||||
| 	/* delete references to contained objects */ | ||||
| 	NULL,                       /* inquiry tp_clear; */ | ||||
|  | ||||
|   /***  Assigned meaning in release 2.1 ***/ | ||||
|   /*** rich comparisons ***/ | ||||
| 	NULL,                       /* richcmpfunc tp_richcompare; */ | ||||
|  | ||||
|   /***  weak reference enabler ***/ | ||||
| 	0,                          /* long tp_weaklistoffset; */ | ||||
|  | ||||
|   /*** Added in release 2.2 ***/ | ||||
| 	/*   Iterators */ | ||||
| 	NULL,                       /* getiterfunc tp_iter; */ | ||||
| 	NULL,                       /* iternextfunc tp_iternext; */ | ||||
|  | ||||
|   /*** Attribute descriptor and subclassing stuff ***/ | ||||
| 	NULL,                       /* struct PyMethodDef *tp_methods; */ | ||||
| 	NULL,                       /* struct PyMemberDef *tp_members; */ | ||||
| 	Library_getseters,          /* struct PyGetSetDef *tp_getset; */ | ||||
| 	NULL,                       /* struct _typeobject *tp_base; */ | ||||
| 	NULL,                       /* PyObject *tp_dict; */ | ||||
| 	NULL,                       /* descrgetfunc tp_descr_get; */ | ||||
| 	NULL,                       /* descrsetfunc tp_descr_set; */ | ||||
| 	0,                          /* long tp_dictoffset; */ | ||||
| 	NULL,                       /* initproc tp_init; */ | ||||
| 	NULL,                       /* allocfunc tp_alloc; */ | ||||
| 	NULL,                       /* newfunc tp_new; */ | ||||
| 	/*  Low-level free-memory routine */ | ||||
| 	NULL,                       /* freefunc tp_free;  */ | ||||
| 	/* For PyObject_IS_GC */ | ||||
| 	NULL,                       /* inquiry tp_is_gc;  */ | ||||
| 	NULL,                       /* PyObject *tp_bases; */ | ||||
| 	/* method resolution order */ | ||||
| 	NULL,                       /* PyObject *tp_mro;  */ | ||||
| 	NULL,                       /* PyObject *tp_cache; */ | ||||
| 	NULL,                       /* PyObject *tp_subclasses; */ | ||||
| 	NULL,                       /* PyObject *tp_weaklist; */ | ||||
| 	NULL | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Library module initialization | ||||
|  */ | ||||
|  | ||||
| static char M_newLibrary_doc[] = "The Blender.lib submodule"; | ||||
|  | ||||
| PyObject *Library_Init( void ) | ||||
| { | ||||
| 	PyObject *submodule; | ||||
|  | ||||
| 	if( PyType_Ready( &Library_Type ) < 0 ) | ||||
| 		return NULL; | ||||
| 	if( PyType_Ready( &LibraryData_Type ) < 0 ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	submodule = Py_InitModule3( "Blender.lib", M_Library_methods, | ||||
| 			M_newLibrary_doc ); | ||||
| 	return submodule; | ||||
| } | ||||
|   | ||||
							
								
								
									
										76
									
								
								source/blender/python/api2_2x/Library.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								source/blender/python/api2_2x/Library.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| /*  | ||||
|  * $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. | ||||
|  * | ||||
|  * This is a new part of Blender. | ||||
|  * | ||||
|  * Contributor(s): Ken Hughes | ||||
|  * | ||||
|  * ***** END GPL/BL DUAL LICENSE BLOCK ***** | ||||
| */ | ||||
|  | ||||
| #ifndef EXPP_LIBRARY_H | ||||
| #define EXPP_LIBRARY_H | ||||
|  | ||||
| #include <Python.h> | ||||
| #include "DNA_scene_types.h" | ||||
| #include "BLI_linklist.h" | ||||
|  | ||||
| #include "blendef.h" | ||||
|  | ||||
| /*****************************************************************************/ | ||||
| /* Python BPy_Library structure definition:        */ | ||||
| /*****************************************************************************/ | ||||
| typedef struct { | ||||
| 	PyObject_HEAD  | ||||
| 	char filename[FILE_MAXDIR + FILE_MAXFILE]; | ||||
| } BPy_Library; | ||||
|  | ||||
| typedef struct { | ||||
| 	PyObject_HEAD  | ||||
| 	LinkNode *iter; | ||||
| 	int type; | ||||
| 	char filename[FILE_MAXDIR + FILE_MAXFILE]; | ||||
| 	char *name; | ||||
| 	enum { | ||||
| 		OBJECT_IS_LINK, | ||||
| 		OBJECT_IS_APPEND, | ||||
| 		OTHER | ||||
| 	} kind; | ||||
| } BPy_LibraryData; | ||||
|  | ||||
| extern PyTypeObject Library_Type; | ||||
| extern PyTypeObject LibraryData_Type; | ||||
|  | ||||
| #define BPy_LibraryData_Check(v)       ((v)->ob_type == &LibraryData_Type) | ||||
| #define BPy_Library_Check(v)       ((v)->ob_type == &Library_Type) | ||||
|  | ||||
| /*****************************************************************************/ | ||||
| /* Module Blender.Library - public functions	 */ | ||||
| /*****************************************************************************/ | ||||
| PyObject *Library_Init( void ); | ||||
| PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name, | ||||
| 		int mode, Scene *scene ); | ||||
|  | ||||
| #endif				/* EXPP_LIBRARY_H */ | ||||
| @@ -105,7 +105,7 @@ | ||||
| #include "NLA.h" | ||||
| #include "Main.h" | ||||
| #include "Scene.h" | ||||
|  | ||||
| #include "Library.h" | ||||
|  | ||||
| #include "Config.h" /* config pydata */ | ||||
|  | ||||
| @@ -746,6 +746,8 @@ static char M_Main_doc[] = "The Blender.Main submodule"; | ||||
| PyObject *Main_Init( void ) | ||||
| { | ||||
| 	PyObject *submodule; | ||||
| 	PyObject *dict; | ||||
|  | ||||
|  | ||||
| 	if( PyType_Ready( &MainSeq_Type ) < 0 ) | ||||
| 		return NULL; | ||||
| @@ -753,6 +755,10 @@ PyObject *Main_Init( void ) | ||||
| 		return NULL;	 | ||||
| 	 | ||||
| 	submodule = Py_InitModule3( "Blender.Main", NULL, M_Main_doc ); | ||||
| 	dict = PyModule_GetDict( submodule ); | ||||
|  | ||||
| 	PyDict_SetItemString( dict, "libraries", Library_Init(  ) ); | ||||
|  | ||||
| 	 | ||||
| 	/* Python Data Types */ | ||||
| 	PyModule_AddObject( submodule, "scenes", MainSeq_CreatePyObject(NULL, ID_SCE) ); | ||||
|   | ||||
| @@ -72,6 +72,7 @@ struct View3D; | ||||
| #include "Metaball.h" | ||||
| #include "IDProp.h" | ||||
| #include "Text3d.h" | ||||
| #include "Library.h" | ||||
|  | ||||
| #include "gen_utils.h" | ||||
| #include "gen_library.h" | ||||
| @@ -1419,6 +1420,13 @@ static PyObject *SceneObSeq_link( BPy_SceneObSeq * self, PyObject *pyobj ) | ||||
| 					      "Cannot modify scene objects while iterating" ); | ||||
| 	*/ | ||||
| 	 | ||||
| 	if( PyTuple_Size(pyobj) == 1 ) { | ||||
| 		BPy_LibraryData *seq = ( BPy_LibraryData * )PyTuple_GET_ITEM( pyobj, 0 ); | ||||
| 		if( BPy_LibraryData_Check( seq ) ) | ||||
| 			return LibraryData_importLibData( seq, seq->name, | ||||
| 					( seq->kind == OBJECT_IS_LINK ? FILE_LINK : 0 ), | ||||
| 					self->bpyscene->scene ); | ||||
| 	} | ||||
| 	return Scene_link(self->bpyscene, pyobj); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -130,6 +130,8 @@ Example:: | ||||
| @type armatures: L{dataIterator} | ||||
| @var actions: iterator for L{action<NLA.Action>} data | ||||
| @type actions: L{dataIterator} | ||||
| @var libraries: L{New library<LibData>} submodule | ||||
| @type libraries: L{New library<LibData>} | ||||
|  | ||||
| """ | ||||
|  | ||||
|   | ||||
							
								
								
									
										137
									
								
								source/blender/python/api2_2x/doc/LibData.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								source/blender/python/api2_2x/doc/LibData.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| # bpy.lib submodule | ||||
|  | ||||
| """ | ||||
| The bpy.libraries submodule. | ||||
|  | ||||
| Libraries | ||||
| ========= | ||||
|  | ||||
| This module provides access to objects stored in .blend files.  With it scripts | ||||
| can append from Blender files to the current scene, like the File->Append | ||||
| menu entry in Blender does.  It allows programmers to use .blend files as | ||||
| data files for their scripts. | ||||
|  | ||||
| @warn: This module is new and being considered as a replacement for the  | ||||
| L{original Library<Library>} module.  Users should stay tuned to see | ||||
| which module is supported in the end. | ||||
|  | ||||
| Example:: | ||||
| 	import bpy | ||||
|  | ||||
| 	scn= bpy.scenes.active                            # get current scene | ||||
| 	lib = bpy.libraries.load('//file.blend')          # open file.blend | ||||
| 	ob = scn.objects.link(lib.objects.append('Cube')) # append Cube object from library to current scene | ||||
| 	mat = lib.objects.link('Material')                # get a link to a material | ||||
| 	me = ob.getData(mesh=1)                           # get mesh data | ||||
| 	me.materials[0] = mat                             # assign linked material to mesh | ||||
| """ | ||||
|  | ||||
| def load(filename): | ||||
|   """ | ||||
|   Select an existing .blend file for use as a library.  Unlike the  | ||||
|   Library module, multiple libraries can be defined at the same time.   | ||||
|    | ||||
|   @type filename: string | ||||
|   @param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location. | ||||
|   @rtype: Library | ||||
|   @return: return a L{Library} object. | ||||
|   """ | ||||
|  | ||||
| class Libraries: | ||||
| 	""" | ||||
| 	The Library object | ||||
| 	================== | ||||
| 	This class provides a unified way to access and manipulate library types | ||||
| 	in Blender. | ||||
| 	It provides access to scenes, objects, meshes, curves, metaballs, | ||||
| 	materials, textures, images, lattices, lamps, cameras, ipos, worlds, | ||||
| 	fonts, texts, sounds, groups, armatures, and actions. | ||||
| 	@ivar filename: The path to the library | ||||
| 	@type filename: string | ||||
| 	@ivar scenes: library L{scene<Scene.Scene>} data | ||||
| 	@type scenes: L{LibData} | ||||
| 	@ivar objects: library L{object<Object.Object>} data | ||||
| 	@type objects: L{LibData} | ||||
| 	@ivar meshes: library L{mesh<Mesh.Mesh>} data | ||||
| 	@type meshes: L{LibData} | ||||
| 	@ivar curves: library L{curve<Curve.Curve>} data | ||||
| 	@type curves: L{LibData} | ||||
| 	@ivar metaballs: library L{metaball<Metaball.Metaball>} data | ||||
| 	@type metaballs: L{LibData} | ||||
| 	@ivar materials: library L{material<Material.Material>} data | ||||
| 	@type materials: L{LibData} | ||||
| 	@ivar textures: library L{texture<Texture.Texture>} data | ||||
| 	@type textures: L{LibData} | ||||
| 	@ivar images: library L{image<Image.Image>} data | ||||
| 	@type images: L{LibData} | ||||
| 	@ivar lattices: library L{lattice<Lattice.Lattice>} data | ||||
| 	@type lattices: L{LibData} | ||||
| 	@ivar lamps: library L{lamp<Lamp.Lamp>} data | ||||
| 	@type lamps: L{LibData} | ||||
| 	@ivar cameras: library L{camera<Camera.Camera>} data | ||||
| 	@type cameras: L{LibData} | ||||
| 	@ivar ipos: library L{ipo<Ipo.Ipo>} data | ||||
| 	@type ipos: L{LibData} | ||||
| 	@ivar worlds: library L{world<World.World>} data | ||||
| 	@type worlds: L{LibData} | ||||
| 	@ivar fonts: library L{font<Font.Font>} data | ||||
| 	@type fonts: L{LibData} | ||||
| 	@ivar texts: library L{text<Text.Text>} data | ||||
| 	@type texts: L{LibData} | ||||
| 	@ivar sounds: library L{sound<Sound.Sound>} data | ||||
| 	@type sounds: L{LibData} | ||||
| 	@ivar groups: library L{group<Group.Group>} data | ||||
| 	@type groups: L{LibData} | ||||
| 	@ivar armatures: library L{armature<Armature.Armature>} data | ||||
| 	@type armatures: L{LibData} | ||||
| 	@ivar actions: library L{action<NLA.Action>} data | ||||
| 	@type actions: L{LibData} | ||||
| 	""" | ||||
|  | ||||
| class LibData: | ||||
| 	""" | ||||
| 	Generic Library Data Access | ||||
| 	=========================== | ||||
| 	This class provides access to a specific type of library data. | ||||
| 	""" | ||||
|  | ||||
| 	def append(name): | ||||
| 		""" | ||||
| 		Append a new datablock from a library. The new copy | ||||
| 		is added to the current .blend file. | ||||
|  | ||||
| 		B{Note}: Blender Objects cannot be appended or linked without linking | ||||
| 		them to a scene.  For this reason, lib.objects.append() returns a | ||||
| 		special "wrapper object" which must be passed to Scene.objects.link() | ||||
| 		or bpy.scenes.active.link() in order to actually create the object. | ||||
| 		So the following code will not create a new object:: | ||||
| 			import bpy | ||||
|  | ||||
| 			scn= bpy.scenes.active                            # get current scene | ||||
| 			lib = bpy.libraries.load('//file.blend')          # open file.blend | ||||
| 			pseudoOb = lib.objects.append('Cube'))            # get an object wrapper | ||||
| 		But this code will:: | ||||
| 			import bpy | ||||
|  | ||||
| 			scn= bpy.scenes.active                            # get current scene | ||||
| 			lib = bpy.libraries.load('//file.blend')          # open file.blend | ||||
| 			pseudoOb = lib.objects.append('Cube'))            # get an object wrapper | ||||
| 			ob = scn.objects.link(pseudoOb)  				  # link to scene | ||||
| 		@rtype: Blender data | ||||
| 		@return: return a Blender datablock or object | ||||
| 		@raise IOError: library cannot be read | ||||
| 		@raise ValueError: library does not contain B{name} | ||||
| 		""" | ||||
| 	 | ||||
| 	def link(name): | ||||
| 		""" | ||||
| 		Link a new datablock from a library.  The linked data is not copied | ||||
| 		into the local .blend file. | ||||
|  | ||||
| 		See L{append} for notes on special handling of Blender Objects. | ||||
| 		@rtype: Blender data | ||||
| 		@return: return a Blender datablock or object | ||||
| 		@raise IOError: library cannot be read | ||||
| 		@raise ValueError: library does not contain B{name} | ||||
| 		""" | ||||
| 		 | ||||
| @@ -11,7 +11,9 @@ can append from Blender files to the current scene, like the File->Append | ||||
| menu entry in Blender does.  It allows programmers to use .blend files as | ||||
| data files for their scripts. | ||||
|  | ||||
| @warn: This is a new, still experimental module. | ||||
| @warn: This module is being considered for deprecation.  Users should | ||||
| consider using the L{new Library<LibData>} module and stay tuned to see | ||||
| which module is supported in the end. | ||||
|  | ||||
| Example:: | ||||
|   import Blender | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ken Hughes
					Ken Hughes