Python API
---------- Support for new bpy.libraries module, which is being proposed to replace the Blender.Library module.
This commit is contained in:
@@ -47,6 +47,7 @@ void *copy_libblock(void *rt);
|
||||
void id_lib_extern(struct ID *id);
|
||||
void id_us_plus(struct ID *id);
|
||||
|
||||
int dup_id(struct ListBase *lb, struct ID *id, const char *name);
|
||||
int new_id(struct ListBase *lb, struct ID *id, const char *name);
|
||||
|
||||
struct ListBase *wich_libbase(struct Main *mainlib, short type);
|
||||
|
||||
@@ -788,7 +788,7 @@ static void sort_alpha_id(ListBase *lb, ID *id)
|
||||
|
||||
}
|
||||
|
||||
int new_id(ListBase *lb, ID *id, const char *tname)
|
||||
int dup_id(ListBase *lb, ID *id, const char *tname)
|
||||
/* only for local blocks: external en indirect blocks already have a unique ID */
|
||||
/* return 1: created a new name */
|
||||
{
|
||||
@@ -876,12 +876,21 @@ int new_id(ListBase *lb, ID *id, const char *tname)
|
||||
/* this format specifier is from hell... */
|
||||
sprintf(id->name+2, "%s.%.3d", left, nr);
|
||||
}
|
||||
|
||||
sort_alpha_id(lb, id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int new_id(ListBase *lb, ID *id, const char *tname)
|
||||
/* only for local blocks: external en indirect blocks already have a unique ID */
|
||||
/* return 1: created a new name */
|
||||
{
|
||||
int result = dup_id( lb, id, tname );
|
||||
|
||||
if( result )
|
||||
sort_alpha_id(lb, id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// next to indirect usage in read/writefile also in editobject.c scene.c
|
||||
void clear_id_newpoins()
|
||||
{
|
||||
|
||||
@@ -219,7 +219,7 @@ BLO_blendhandle_close(
|
||||
char *BLO_gethome(void);
|
||||
int BLO_has_bfile_extension(char *str);
|
||||
void BLO_library_append(struct SpaceFile *sfile, char *dir, int idcode);
|
||||
void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag);
|
||||
void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag, struct Scene *scene);
|
||||
|
||||
BlendFileData* blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r);
|
||||
|
||||
|
||||
@@ -7282,7 +7282,7 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
|
||||
|
||||
/* common routine to append/link something from a library */
|
||||
|
||||
static void library_append( SpaceFile *sfile, char *dir, int idcode,
|
||||
static void library_append( Scene *scene, SpaceFile *sfile, char *dir, int idcode,
|
||||
int totsel, FileData *fd)
|
||||
{
|
||||
Main *mainl;
|
||||
@@ -7299,13 +7299,13 @@ static void library_append( SpaceFile *sfile, char *dir, int idcode,
|
||||
curlib= mainl->curlib;
|
||||
|
||||
if(totsel==0) {
|
||||
append_named_part(fd, mainl, G.scene, sfile->file, idcode, sfile->flag);
|
||||
append_named_part(fd, mainl, scene, sfile->file, idcode, sfile->flag);
|
||||
}
|
||||
else {
|
||||
int a;
|
||||
for(a=0; a<sfile->totfile; a++) {
|
||||
if(sfile->filelist[a].flags & ACTIVE) {
|
||||
append_named_part(fd, mainl, G.scene, sfile->filelist[a].relname, idcode, sfile->flag);
|
||||
append_named_part(fd, mainl, scene, sfile->filelist[a].relname, idcode, sfile->flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7333,9 +7333,9 @@ static void library_append( SpaceFile *sfile, char *dir, int idcode,
|
||||
|
||||
/* give a base to loose objects. If group append, do it for objects too */
|
||||
if(idcode==ID_GR)
|
||||
give_base_to_objects(G.scene, &(G.main->object), (sfile->flag & FILE_LINK)?NULL:curlib);
|
||||
give_base_to_objects(scene, &(G.main->object), (sfile->flag & FILE_LINK)?NULL:curlib);
|
||||
else
|
||||
give_base_to_objects(G.scene, &(G.main->object), NULL);
|
||||
give_base_to_objects(scene, &(G.main->object), NULL);
|
||||
|
||||
/* has been removed... erm, why? s..ton) */
|
||||
/* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
|
||||
@@ -7353,7 +7353,8 @@ static void library_append( SpaceFile *sfile, char *dir, int idcode,
|
||||
/* append to G.scene */
|
||||
/* this should probably be moved into the Python code anyway */
|
||||
|
||||
void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag)
|
||||
void BLO_script_library_append(BlendHandle *bh, char *dir, char *name,
|
||||
int idcode, short flag, Scene *scene )
|
||||
{
|
||||
SpaceFile sfile;
|
||||
|
||||
@@ -7364,7 +7365,7 @@ void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcod
|
||||
|
||||
/* try to append the requested object */
|
||||
|
||||
library_append( &sfile, dir, idcode, 0, (FileData *)bh );
|
||||
library_append( scene, &sfile, dir, idcode, 0, (FileData *)bh );
|
||||
|
||||
/* do we need to do this? */
|
||||
DAG_scene_sort(G.scene);
|
||||
@@ -7407,7 +7408,7 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
|
||||
|
||||
if(sfile->flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
|
||||
|
||||
library_append( sfile, dir, idcode, totsel, fd );
|
||||
library_append( G.scene, sfile, dir, idcode, totsel, fd );
|
||||
|
||||
/* when not linking (appending)... */
|
||||
if((sfile->flag & FILE_LINK)==0) {
|
||||
|
||||
@@ -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