Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Hughes <khughes@pacific.edu>2007-03-21 05:23:28 +0300
committerKen Hughes <khughes@pacific.edu>2007-03-21 05:23:28 +0300
commit3a834803ef5d74d68d5aa37b9a23f205a473d27f (patch)
tree10821ce011ca877281ef494dacdcaefde886990b /source/blender/python/api2_2x/Library.c
parenta6db9c59494c1ecf00ba165fff3d9007f0b0fe32 (diff)
Python API
---------- Support for new bpy.libraries module, which is being proposed to replace the Blender.Library module.
Diffstat (limited to 'source/blender/python/api2_2x/Library.c')
-rw-r--r--source/blender/python/api2_2x/Library.c776
1 files changed, 759 insertions, 17 deletions
diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c
index 4a22540a0ae..4251b83585d 100644
--- a/source/blender/python/api2_2x/Library.c
+++ b/source/blender/python/api2_2x/Library.c
@@ -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;
+}