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:
authorWillian Padovani Germano <wpgermano@gmail.com>2004-04-25 00:04:37 +0400
committerWillian Padovani Germano <wpgermano@gmail.com>2004-04-25 00:04:37 +0400
commit382297b68753b1d17d6e57846206d086fde251b0 (patch)
tree3aec01ecd44aed5a2376f3311791d63d560e9dbb
parente5e4c0fc4fc06228523993e088b7e2bdc8a60a47 (diff)
BPython:
- New module + doc: Blender.Library: It's like File->Append, loads datablocks from .blend files. - small updates to fix warnings and accomodate for the new module, in readfile.[ch] - New Blender.sys module function: time, a wrapper of the PIL get time function. - Updated original makefile and scons builds.
-rw-r--r--source/blender/blenloader/BLO_readfile.h1
-rw-r--r--source/blender/blenloader/intern/readfile.c48
-rw-r--r--source/blender/python/SConscript2
-rw-r--r--source/blender/python/api2_2x/Blender.c309
-rw-r--r--source/blender/python/api2_2x/Blender.h20
-rw-r--r--source/blender/python/api2_2x/Library.c360
-rw-r--r--source/blender/python/api2_2x/Makefile1
-rw-r--r--source/blender/python/api2_2x/Sys.c8
-rw-r--r--source/blender/python/api2_2x/Sys.h7
-rw-r--r--source/blender/python/api2_2x/doc/Blender.py1
-rw-r--r--source/blender/python/api2_2x/doc/Library.py110
-rw-r--r--source/blender/python/api2_2x/doc/Sys.py10
-rw-r--r--source/blender/python/api2_2x/modules.h1
13 files changed, 706 insertions, 172 deletions
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 66b3729d860..3093160139b 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -214,6 +214,7 @@ 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);
BlendFileData* blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 3ce03aca4a3..6984f772c42 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -48,6 +48,7 @@
#include <stdlib.h> // for getenv atoi
#include <fcntl.h> // for open
#include <string.h> // for strcasecmp strrchr strncmp strstr
+#include <math.h> // for fabs
#ifndef WIN32
#include <unistd.h> // for read close
@@ -2698,7 +2699,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
ID *id;
ListBase *lb;
- char *str;
+ char *str = NULL;
if(bhead->code==ID_ID) {
ID *linkedid= (ID *)(bhead + 1); /* BHEAD+DATA dependancy */
@@ -4862,13 +4863,12 @@ static void give_base_to_objects(Scene *sce, ListBase *lb)
}
#endif
-static void append_named_part(SpaceFile *sfile, Main *mainvar, Scene *scene, char *name, int idcode)
+static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *name, int idcode)
{
Object *ob;
Base *base;
BHead *bhead;
ID *id;
- FileData *fd= (FileData*) sfile->libfiledata;
int afbreek=0;
bhead = blo_firstbhead(fd);
@@ -4933,6 +4933,38 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
}
}
+/* this is a version of BLO_library_append needed by the BPython API, so
+ * scripts can load data from .blend files -- see Blender.Library module.*/
+
+/* append to G.scene */
+void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode)
+{
+ ListBase mainlist;
+ Main *mainl;
+ FileData *fd = (FileData *)bh;
+
+ mainlist.first= mainlist.last= G.main;
+ G.main->next= NULL;
+
+ /* make mains */
+ blo_split_main(&mainlist);
+
+ /* which one do we need? */
+ mainl = blo_find_main(&mainlist, dir);
+
+ append_named_part(fd, mainl, G.scene, name, idcode);
+
+ /* make main consistant */
+ expand_main(fd, mainl);
+
+ /* do this when expand found other libs */
+ read_libraries(fd, &mainlist);
+
+ blo_join_main(&mainlist);
+ G.main= mainlist.first;
+
+ lib_link_all(fd, G.main);
+}
/* append to G.scene */
void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
@@ -4977,12 +5009,12 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
mainl = blo_find_main(&mainlist, dir);
if(totsel==0) {
- append_named_part(sfile, mainl, G.scene, sfile->file, idcode);
+ append_named_part(fd, mainl, G.scene, sfile->file, idcode);
}
else {
for(a=0; a<sfile->totfile; a++) {
if(sfile->filelist[a].flags & ACTIVE) {
- append_named_part(sfile, mainl, G.scene, sfile->filelist[a].relname, idcode);
+ append_named_part(fd, mainl, G.scene, sfile->filelist[a].relname, idcode);
}
}
}
@@ -5029,7 +5061,7 @@ static int mainvar_count_libread_blocks(Main *mainvar)
static void read_libraries(FileData *basefd, ListBase *mainlist)
{
- Main *main= mainlist->first;
+ Main *mainl= mainlist->first;
Main *mainptr;
ListBase *lbarray[30];
int a, doit= 1;
@@ -5038,7 +5070,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
doit= 0;
/* test 1: read libdata */
- mainptr= main->next;
+ mainptr= mainl->next;
while(mainptr) {
int tot= mainvar_count_libread_blocks(mainptr);
@@ -5092,7 +5124,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
mainptr= mainptr->next;
}
}
- mainptr= main->next;
+ mainptr= mainl->next;
while(mainptr) {
/* test if there are unread libblocks */
a= set_listbasepointers(mainptr, lbarray);
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index 9377e45faf6..41fb4c082a2 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -18,6 +18,7 @@ source_files = ['BPY_interface.c',
'api2_2x/World.c',
'api2_2x/Lamp.c',
'api2_2x/Lattice.c',
+ 'api2_2x/Library.c',
'api2_2x/Curve.c',
'api2_2x/Armature.c',
'api2_2x/Bone.c',
@@ -53,6 +54,7 @@ source_files = ['BPY_interface.c',
python_env.Append (CPPPATH = ['api2_2x',
'../blenkernel',
'../blenlib',
+ '../blenloader',
'../render/extern/include',
'../makesdna',
'#/intern/guardedalloc',
diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c
index 66d82c9509c..4671fed9e60 100644
--- a/source/blender/python/api2_2x/Blender.c
+++ b/source/blender/python/api2_2x/Blender.c
@@ -17,7 +17,7 @@
*
* 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.
+ * 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.
@@ -35,205 +35,206 @@
#include "Blender.h"
/*****************************************************************************/
-/* Global variables */
+/* Global variables */
/*****************************************************************************/
PyObject *g_blenderdict;
/*****************************************************************************/
-/* Function: Blender_Set */
-/* Python equivalent: Blender.Set */
+/* Function: Blender_Set */
+/* Python equivalent: Blender.Set */
/*****************************************************************************/
PyObject *Blender_Set (PyObject *self, PyObject *args)
{
- char * name;
- PyObject * arg;
- int framenum;
-
- if (!PyArg_ParseTuple(args, "sO", &name, &arg))
- {
- /* TODO: Do we need to generate a nice error message here? */
- return (NULL);
- }
-
- if (StringEqual (name, "curframe"))
- {
- if (!PyArg_Parse(arg, "i", &framenum))
- {
- /* TODO: Do we need to generate a nice error message here? */
- return (NULL);
- }
-
- G.scene->r.cfra = framenum;
-
- update_for_newframe();
- }
- else
- {
- return (PythonReturnErrorObject (PyExc_AttributeError,
- "bad request identifier"));
- }
- return ( PythonIncRef (Py_None) );
+ char * name;
+ PyObject * arg;
+ int framenum;
+
+ if (!PyArg_ParseTuple(args, "sO", &name, &arg))
+ {
+ /* TODO: Do we need to generate a nice error message here? */
+ return (NULL);
+ }
+
+ if (StringEqual (name, "curframe"))
+ {
+ if (!PyArg_Parse(arg, "i", &framenum))
+ {
+ /* TODO: Do we need to generate a nice error message here? */
+ return (NULL);
+ }
+
+ G.scene->r.cfra = framenum;
+
+ update_for_newframe();
+ }
+ else
+ {
+ return (PythonReturnErrorObject (PyExc_AttributeError,
+ "bad request identifier"));
+ }
+ return ( PythonIncRef (Py_None) );
}
/*****************************************************************************/
-/* Function: Blender_Get */
-/* Python equivalent: Blender.Get */
+/* Function: Blender_Get */
+/* Python equivalent: Blender.Get */
/*****************************************************************************/
PyObject *Blender_Get (PyObject *self, PyObject *args)
{
- PyObject * object;
- PyObject * dict;
- char * str;
-
- if (!PyArg_ParseTuple (args, "O", &object))
- {
- /* TODO: Do we need to generate a nice error message here? */
- return (NULL);
- }
-
- if (PyString_Check (object))
- {
- str = PyString_AsString (object);
-
- if (StringEqual (str, "curframe"))
- {
- return ( PyInt_FromLong (G.scene->r.cfra) );
- }
- if (StringEqual (str, "curtime"))
- {
- return ( PyFloat_FromDouble (frame_to_float (G.scene->r.cfra) ) );
- }
- if (StringEqual (str, "staframe"))
- {
- return ( PyInt_FromLong (G.scene->r.sfra) );
- }
- if (StringEqual (str, "endframe"))
- {
- return ( PyInt_FromLong (G.scene->r.efra) );
- }
- if (StringEqual (str, "filename"))
- {
- return ( PyString_FromString (G.sce) );
- }
- /* According to the old file (opy_blender.c), the following if
- statement is a quick hack and needs some clean up. */
- if (StringEqual (str, "vrmloptions"))
- {
- dict = PyDict_New ();
-
- PyDict_SetItemString (dict, "twoside",
- PyInt_FromLong (U.vrmlflag & USER_VRML_TWOSIDED));
-
- PyDict_SetItemString (dict, "layers",
- PyInt_FromLong (U.vrmlflag & USER_VRML_LAYERS));
-
- PyDict_SetItemString (dict, "autoscale",
- PyInt_FromLong (U.vrmlflag & USER_VRML_AUTOSCALE));
-
- return (dict);
- } /* End 'quick hack' part. */
- if (StringEqual (str, "version"))
- {
- return ( PyInt_FromLong (G.version) );
- }
- /* TODO: Do we want to display a usefull message here that the
- requested data is unknown?
- else
- {
- return (PythonReturnErrorObject (..., "message") );
- }
- */
- }
- else
- {
- return (PythonReturnErrorObject (PyExc_AttributeError,
- "expected string argument"));
- }
-
- return (PythonReturnErrorObject (PyExc_AttributeError,
- "bad request identifier"));
+ PyObject * object;
+ PyObject * dict;
+ char * str;
+
+ if (!PyArg_ParseTuple (args, "O", &object))
+ {
+ /* TODO: Do we need to generate a nice error message here? */
+ return (NULL);
+ }
+
+ if (PyString_Check (object))
+ {
+ str = PyString_AsString (object);
+
+ if (StringEqual (str, "curframe"))
+ {
+ return ( PyInt_FromLong (G.scene->r.cfra) );
+ }
+ if (StringEqual (str, "curtime"))
+ {
+ return ( PyFloat_FromDouble (frame_to_float (G.scene->r.cfra) ) );
+ }
+ if (StringEqual (str, "staframe"))
+ {
+ return ( PyInt_FromLong (G.scene->r.sfra) );
+ }
+ if (StringEqual (str, "endframe"))
+ {
+ return ( PyInt_FromLong (G.scene->r.efra) );
+ }
+ if (StringEqual (str, "filename"))
+ {
+ return ( PyString_FromString (G.sce) );
+ }
+ /* According to the old file (opy_blender.c), the following if
+ statement is a quick hack and needs some clean up. */
+ if (StringEqual (str, "vrmloptions"))
+ {
+ dict = PyDict_New ();
+
+ PyDict_SetItemString (dict, "twoside",
+ PyInt_FromLong (U.vrmlflag & USER_VRML_TWOSIDED));
+
+ PyDict_SetItemString (dict, "layers",
+ PyInt_FromLong (U.vrmlflag & USER_VRML_LAYERS));
+
+ PyDict_SetItemString (dict, "autoscale",
+ PyInt_FromLong (U.vrmlflag & USER_VRML_AUTOSCALE));
+
+ return (dict);
+ } /* End 'quick hack' part. */
+ if (StringEqual (str, "version"))
+ {
+ return ( PyInt_FromLong (G.version) );
+ }
+ /* TODO: Do we want to display a usefull message here that the
+ requested data is unknown?
+ else
+ {
+ return (PythonReturnErrorObject (..., "message") );
+ }
+ */
+ }
+ else
+ {
+ return (PythonReturnErrorObject (PyExc_AttributeError,
+ "expected string argument"));
+ }
+
+ return (PythonReturnErrorObject (PyExc_AttributeError,
+ "bad request identifier"));
}
/*****************************************************************************/
-/* Function: Blender_Redraw */
-/* Python equivalent: Blender.Redraw */
+/* Function: Blender_Redraw */
+/* Python equivalent: Blender.Redraw */
/*****************************************************************************/
PyObject *Blender_Redraw(PyObject *self, PyObject *args)
{
- int wintype = SPACE_VIEW3D;
+ int wintype = SPACE_VIEW3D;
- if (!PyArg_ParseTuple (args, "|i", &wintype))
- {
- return EXPP_ReturnPyObjError (PyExc_TypeError,
- "expected int argument (or nothing)");
- }
+ if (!PyArg_ParseTuple (args, "|i", &wintype))
+ {
+ return EXPP_ReturnPyObjError (PyExc_TypeError,
+ "expected int argument (or nothing)");
+ }
- return M_Window_Redraw(self, Py_BuildValue("(i)", wintype));
+ return M_Window_Redraw(self, Py_BuildValue("(i)", wintype));
}
/*****************************************************************************/
-/* Function: Blender_ReleaseGlobalDict */
-/* Python equivalent: Blender.ReleaseGlobalDict */
-/* Description: Deprecated function. */
+/* Function: Blender_ReleaseGlobalDict */
+/* Python equivalent: Blender.ReleaseGlobalDict */
+/* Description: Deprecated function. */
/*****************************************************************************/
PyObject *Blender_ReleaseGlobalDict(PyObject *self, PyObject *args)
{
Py_INCREF(Py_None);
- return Py_None;
+ return Py_None;
}
/*****************************************************************************/
-/* Function: Blender_Quit */
-/* Python equivalent: Blender.Quit */
+/* Function: Blender_Quit */
+/* Python equivalent: Blender.Quit */
/*****************************************************************************/
PyObject *Blender_Quit(PyObject *self)
{
exit_usiblender();
Py_INCREF(Py_None);
- return Py_None;
+ return Py_None;
}
/*****************************************************************************/
-/* Function: initBlender */
+/* Function: initBlender */
/*****************************************************************************/
void M_Blender_Init (void)
{
- PyObject * module;
- PyObject * dict;
+ PyObject * module;
+ PyObject * dict;
- g_blenderdict = NULL;
+ g_blenderdict = NULL;
- /* TODO: create a docstring for the Blender module */
- module = Py_InitModule3("Blender", Blender_methods, NULL);
+ /* TODO: create a docstring for the Blender module */
+ module = Py_InitModule3("Blender", Blender_methods, NULL);
types_InitAll(); /* set all our pytypes to &PyType_Type*/
- dict = PyModule_GetDict (module);
- g_blenderdict = dict;
- PyDict_SetItemString (dict, "Types", Types_Init());
- PyDict_SetItemString (dict, "sys", sys_Init());
- PyDict_SetItemString (dict, "Registry", Registry_Init());
- PyDict_SetItemString (dict, "Scene", Scene_Init());
- PyDict_SetItemString (dict, "Object", Object_Init());
- PyDict_SetItemString (dict, "Material", Material_Init());
- PyDict_SetItemString (dict, "Camera", Camera_Init());
- PyDict_SetItemString (dict, "Lamp", Lamp_Init());
- PyDict_SetItemString (dict, "Lattice", Lattice_Init());
- PyDict_SetItemString (dict, "Curve", Curve_Init());
- PyDict_SetItemString (dict, "Armature", Armature_Init());
- PyDict_SetItemString (dict, "Ipo", Ipo_Init());
- PyDict_SetItemString (dict, "IpoCurve", IpoCurve_Init());
- PyDict_SetItemString (dict, "Metaball", Metaball_Init());
- PyDict_SetItemString (dict, "Image", Image_Init());
- PyDict_SetItemString (dict, "Window", Window_Init());
- PyDict_SetItemString (dict, "Draw", Draw_Init());
- PyDict_SetItemString (dict, "BGL", BGL_Init());
- PyDict_SetItemString (dict, "Effect", Effect_Init());
- PyDict_SetItemString (dict, "Text", Text_Init());
- PyDict_SetItemString (dict, "World", World_Init());
- PyDict_SetItemString (dict, "Texture", Texture_Init());
- PyDict_SetItemString (dict, "NMesh", NMesh_Init());
- PyDict_SetItemString (dict, "Noise", Noise_Init());
- PyDict_SetItemString (dict, "Mathutils",Mathutils_Init());
+ dict = PyModule_GetDict (module);
+ g_blenderdict = dict;
+ PyDict_SetItemString (dict, "Types", Types_Init());
+ PyDict_SetItemString (dict, "sys", sys_Init());
+ PyDict_SetItemString (dict, "Registry", Registry_Init());
+ PyDict_SetItemString (dict, "Scene", Scene_Init());
+ PyDict_SetItemString (dict, "Object", Object_Init());
+ PyDict_SetItemString (dict, "Material", Material_Init());
+ PyDict_SetItemString (dict, "Camera", Camera_Init());
+ PyDict_SetItemString (dict, "Lamp", Lamp_Init());
+ PyDict_SetItemString (dict, "Lattice", Lattice_Init());
+ PyDict_SetItemString (dict, "Curve", Curve_Init());
+ PyDict_SetItemString (dict, "Armature", Armature_Init());
+ PyDict_SetItemString (dict, "Ipo", Ipo_Init());
+ PyDict_SetItemString (dict, "IpoCurve", IpoCurve_Init());
+ PyDict_SetItemString (dict, "Metaball", Metaball_Init());
+ PyDict_SetItemString (dict, "Image", Image_Init());
+ PyDict_SetItemString (dict, "Window", Window_Init());
+ PyDict_SetItemString (dict, "Draw", Draw_Init());
+ PyDict_SetItemString (dict, "BGL", BGL_Init());
+ PyDict_SetItemString (dict, "Effect", Effect_Init());
+ PyDict_SetItemString (dict, "Text", Text_Init());
+ PyDict_SetItemString (dict, "World", World_Init());
+ PyDict_SetItemString (dict, "Texture", Texture_Init());
+ PyDict_SetItemString (dict, "NMesh", NMesh_Init());
+ PyDict_SetItemString (dict, "Noise", Noise_Init());
+ PyDict_SetItemString (dict, "Mathutils",Mathutils_Init());
+ PyDict_SetItemString (dict, "Library", Library_Init());
}
diff --git a/source/blender/python/api2_2x/Blender.h b/source/blender/python/api2_2x/Blender.h
index 12417651637..ebbae7ff63a 100644
--- a/source/blender/python/api2_2x/Blender.h
+++ b/source/blender/python/api2_2x/Blender.h
@@ -17,7 +17,7 @@
*
* 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.
+ * 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.
@@ -51,7 +51,7 @@
PyObject *M_Window_Redraw(PyObject *self, PyObject *args);
/*****************************************************************************/
-/* Python API function prototypes for the Blender module. */
+/* Python API function prototypes for the Blender module. */
/*****************************************************************************/
PyObject *Blender_Set (PyObject *self, PyObject *args);
PyObject *Blender_Get (PyObject *self, PyObject *args);
@@ -60,9 +60,9 @@ PyObject *Blender_ReleaseGlobalDict(PyObject *self, PyObject *args);
PyObject *Blender_Quit(PyObject *self);
/*****************************************************************************/
-/* The following string definitions are used for documentation strings. */
-/* In Python these will be written to the console when doing a */
-/* Blender.__doc__ */
+/* The following string definitions are used for documentation strings. */
+/* In Python these will be written to the console when doing a */
+/* Blender.__doc__ */
/*****************************************************************************/
char Blender_Set_doc[] =
"(request, data) - Update settings in Blender\n\
@@ -90,15 +90,15 @@ char Blender_Quit_doc[] =
"() - Quit Blender. Experimental, please use with caution.";
/*****************************************************************************/
-/* Python method structure definition. */
+/* Python method structure definition. */
/*****************************************************************************/
struct PyMethodDef Blender_methods[] = {
- {"Set", Blender_Set, METH_VARARGS, Blender_Set_doc},
- {"Get", Blender_Get, METH_VARARGS, Blender_Get_doc},
+ {"Set", Blender_Set, METH_VARARGS, Blender_Set_doc},
+ {"Get", Blender_Get, METH_VARARGS, Blender_Get_doc},
{"Redraw", Blender_Redraw, METH_VARARGS, Blender_Redraw_doc},
- {"Quit", (PyCFunction)Blender_Quit, METH_NOARGS, Blender_Quit_doc},
+ {"Quit", (PyCFunction)Blender_Quit, METH_NOARGS, Blender_Quit_doc},
{"ReleaseGlobalDict", &Blender_ReleaseGlobalDict,
- METH_VARARGS, Blender_ReleaseGlobalDict_doc},
+ METH_VARARGS, Blender_ReleaseGlobalDict_doc},
{NULL, NULL}
};
diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c
new file mode 100644
index 00000000000..6a0a958c9d7
--- /dev/null
+++ b/source/blender/python/api2_2x/Library.c
@@ -0,0 +1,360 @@
+/**
+ * $Id$
+ *
+ * Blender.Library BPython module implementation.
+ * This submodule has functions to append data from .blend files.
+ *
+ * ***** 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): Willian P. Germano
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+*/
+
+#include <Python.h>
+#include <stdio.h>
+
+#include "BKE_displist.h" /* for set_displist_onlyzero */
+#include "BKE_font.h" /* for text_to_curve */
+#include "BKE_library.h" /* for all_local */
+#include "BLO_readfile.h"
+#include "BLI_linklist.h"
+#include "MEM_guardedalloc.h"
+
+#include "gen_utils.h"
+#include "modules.h"
+
+/**
+ * Global variables.
+ */
+static BlendHandle *bpy_openlib; /* ptr to the open .blend file */
+static char *bpy_openlibname; /* its pathname */
+
+/**
+ * Function prototypes for the Library submodule.
+ */
+static PyObject *M_Library_Open(PyObject *self, PyObject *args);
+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 *M_Library_LinkableGroups(PyObject *self);
+
+/**
+ * Module doc strings.
+ */
+static char M_Library_doc[]=
+"The Blender.Library submodule:\n\n\
+This module gives access to .blend files, using them as libraries of\n\
+data that can be loaded into the current scene in Blender.";
+
+static char Library_Open_doc[] =
+"(filename) - Open the given .blend file for access to its objects.\n\
+If another library file is still open, it's closed automatically.";
+
+static char Library_Close_doc[] =
+"() - Close the currently open library file, if any.";
+
+static char Library_GetName_doc[] =
+"() - Get the filename of the currently open library file, if any.";
+
+static char Library_Datablocks_doc[] =
+"(datablock) - List all datablocks of the given type in the currently\n\
+open library file.\n\
+(datablock) - datablock name as a string: Object, Mesh, etc.";
+
+static char Library_Load_doc[] =
+"(name, datablock [,update = 1]) - Append object 'name' of type 'datablock'\n\
+from the open library file to the current scene.\n\
+(name) - (str) the name of the object.\n\
+(datablock) - (str) the datablock of the object.\n\
+(update = 1) - (int) if non-zero, all display lists are recalculated and the\n\
+links are updated. This is slow, set it to zero if you have more than one\n\
+object to load, then call Library.Update() after loading them all.";
+
+static char Library_Update_doc[] =
+"() - Update the current scene, linking all loaded library objects and\n\
+remaking all display lists. This is slow, call it only once after loading\n\
+all objects (load each of them with update = 0:\n\
+Library.Load(name, datablock, 0), or the update will be automatic, repeated\n\
+for each loaded object.";
+
+static char Library_LinkableGroups_doc[] =
+"() - Get all linkable groups from the open .blend library file.";
+
+/**
+ * Python method structure definition for Blender.Library submodule.
+ */
+struct PyMethodDef M_Library_methods[] = {
+ {"Open", M_Library_Open, METH_VARARGS, Library_Open_doc},
+ {"Close",(PyCFunction)M_Library_Close, METH_NOARGS, Library_Close_doc},
+ {"GetName",(PyCFunction)M_Library_GetName, METH_NOARGS, Library_GetName_doc},
+ {"Update",(PyCFunction)M_Library_Update, METH_NOARGS, Library_Update_doc},
+ {"Datablocks", M_Library_Datablocks, METH_VARARGS, Library_Datablocks_doc},
+ {"Load", M_Library_Load, METH_VARARGS, Library_Load_doc},
+ {"LinkableGroups",(PyCFunction)M_Library_LinkableGroups,
+ METH_NOARGS, Library_LinkableGroups_doc},
+ {NULL, NULL, 0, NULL}
+};
+
+/* Submodule Python functions: */
+
+/**
+ * Open a new .blend file.
+ * 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)
+{
+ char *fname = NULL;
+ int len = 0;
+
+ if (!PyArg_ParseTuple (args, "s", &fname)) {
+ return EXPP_ReturnPyObjError (PyExc_TypeError,
+ "expected a .blend filename");
+ }
+
+ if (bpy_openlib) {
+ M_Library_Close(self);
+ Py_DECREF(Py_None); /* incref'ed by above function */
+ }
+
+ bpy_openlib = BLO_blendhandle_from_file(fname);
+
+ if (!bpy_openlib) return Py_BuildValue("i", 0);
+
+ len = strlen(fname) + 1; /* +1 for terminating '\0' */
+
+ bpy_openlibname = MEM_mallocN(len, "bpy_openlibname");
+
+ if (bpy_openlibname)
+ PyOS_snprintf (bpy_openlibname, len, "%s", fname);
+
+ return Py_BuildValue("i", 1);
+}
+
+/**
+ * Close the current .blend file, if any.
+ */
+PyObject *M_Library_Close(PyObject *self)
+{
+ if (bpy_openlib) {
+ BLO_blendhandle_close(bpy_openlib);
+ bpy_openlib = NULL;
+ }
+
+ if (bpy_openlibname) {
+ MEM_freeN (bpy_openlibname);
+ bpy_openlibname = NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/**
+ * Get the filename of the currently open library file, if any.
+ */
+PyObject *M_Library_GetName(PyObject *self)
+{
+ if (bpy_openlib && bpy_openlibname)
+ return Py_BuildValue("s", bpy_openlibname);
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+/**
+ * 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)
+{
+ char *name = NULL;
+ int blocktype = 0;
+ LinkNode *l = NULL, *names = NULL;
+ PyObject *list = NULL;
+
+ if (!bpy_openlib) {
+ return EXPP_ReturnPyObjError(PyExc_IOError,
+ "no library file: open one first with Blender.Lib_Open(filename)");
+ }
+
+ if (!PyArg_ParseTuple (args, "s", &name)) {
+ return EXPP_ReturnPyObjError (PyExc_TypeError,
+ "expected a string (datablock type) as argument.");
+ }
+
+ blocktype = (int)BLO_idcode_from_name(name);
+
+ if (!blocktype) {
+ return EXPP_ReturnPyObjError (PyExc_NameError,
+ "no such Blender datablock type");
+ }
+
+ names = BLO_blendhandle_get_datablock_names(bpy_openlib, blocktype);
+
+ if (names) {
+ int counter = 0;
+ list = PyList_New(BLI_linklist_length(names));
+ for (l = names; l; l = l->next) {
+ PyList_SET_ITEM(list, counter, Py_BuildValue("s", (char *)l->link));
+ counter++;
+ }
+ BLI_linklist_free(names, free); /* free linklist *and* each node's data */
+ return list;
+ }
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+/**
+ * Return a list with the names of all linkable groups in the
+ * open library file.
+ */
+PyObject *M_Library_LinkableGroups(PyObject *self)
+{
+ LinkNode *l = NULL, *names = NULL;
+ PyObject *list = NULL;
+
+ if (!bpy_openlib) {
+ return EXPP_ReturnPyObjError(PyExc_IOError,
+ "no library file: open one first with Blender.Lib_Open(filename)");
+ }
+
+ names = BLO_blendhandle_get_linkable_groups(bpy_openlib);
+
+ if (names) {
+ int counter = 0;
+ list = PyList_New(BLI_linklist_length(names));
+ for (l = names; l; l = l->next) {
+ PyList_SET_ITEM(list, counter, Py_BuildValue("s", (char *)l->link));
+ counter++;
+ }
+ BLI_linklist_free(names, free); /* free linklist *and* each node's data */
+ return list;
+ }
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+/**
+ * Load (append) a given datablock of a given datablock type
+ * to the current scene.
+ */
+PyObject *M_Library_Load(PyObject *self, PyObject *args)
+{
+ char *name = NULL;
+ char *base = NULL;
+ int update = 1;
+ int blocktype = 0;
+
+ if (!bpy_openlib) {
+ return EXPP_ReturnPyObjError(PyExc_IOError,
+ "no library file: you need to open one, first.");
+ }
+
+ if (!PyArg_ParseTuple (args, "ss|i", &name, &base, &update)) {
+ return EXPP_ReturnPyObjError (PyExc_TypeError,
+ "expected two strings as arguments.");
+ }
+
+ blocktype = (int)BLO_idcode_from_name(base);
+
+ if (!blocktype) {
+ return EXPP_ReturnPyObjError (PyExc_NameError,
+ "no such Blender datablock type");
+ }
+
+ BLO_script_library_append(bpy_openlib, bpy_openlibname, name, blocktype);
+
+ if (update) {
+ M_Library_Update(self);
+ Py_DECREF(Py_None); /* incref'ed by above function */
+ }
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+/**
+ * Update all links and remake displists.
+ */
+PyObject *M_Library_Update(PyObject *self)
+{ /* code adapted from do_library_append in src/filesel.c: */
+ Object *ob = NULL;
+ Library *lib = NULL;
+
+ ob = G.main->object.first;
+ set_displist_onlyzero(1);
+ while (ob) {
+ if (ob->id.lib) {
+ if (ob->type==OB_FONT) {
+ Curve *cu= ob->data;
+ if (cu->nurb.first==0) text_to_curve(ob, 0);
+ }
+ makeDispList(ob);
+ }
+ else {
+ if (ob->type == OB_MESH && ob->parent && ob->parent->type == OB_LATTICE)
+ makeDispList(ob);
+ }
+
+ ob = ob->id.next;
+ }
+ set_displist_onlyzero(0);
+
+ if (bpy_openlibname) {
+ strcpy(G.lib, bpy_openlibname);
+
+ /* and now find the latest append lib file */
+ lib = G.main->library.first;
+ while (lib) {
+ if (strcmp(bpy_openlibname, lib->name) == 0) break;
+ lib = lib->id.next;
+ }
+ all_local(lib);
+ }
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+/**
+ * Initialize the Blender.Library submodule.
+ * Called by Blender_Init in Blender.c .
+ * @return the registered submodule.
+ */
+PyObject *Library_Init (void)
+{
+ PyObject *submod;
+
+ submod = Py_InitModule3("Blender.Library", M_Library_methods, M_Library_doc);
+
+ return submod;
+}
diff --git a/source/blender/python/api2_2x/Makefile b/source/blender/python/api2_2x/Makefile
index cdefeee815d..545e5cb0875 100644
--- a/source/blender/python/api2_2x/Makefile
+++ b/source/blender/python/api2_2x/Makefile
@@ -50,6 +50,7 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I../../blenlib
+CPPFLAGS += -I../../blenloader
CPPFLAGS += -I../../include
CPPFLAGS += -I../../render/extern/include
CPPFLAGS += -I$(NAN_BMFONT)/include
diff --git a/source/blender/python/api2_2x/Sys.c b/source/blender/python/api2_2x/Sys.c
index 99b5d3488b5..56f3a64d489 100644
--- a/source/blender/python/api2_2x/Sys.c
+++ b/source/blender/python/api2_2x/Sys.c
@@ -30,6 +30,7 @@
*/
#include "BKE_utildefines.h"
+#include "PIL_time.h"
#include "Sys.h"
@@ -168,3 +169,10 @@ static PyObject *M_sys_splitext (PyObject *self, PyObject *args)
return Py_BuildValue("ss", path, ext);
}
+
+static PyObject *M_sys_time (PyObject *self)
+{
+ double t = PIL_check_seconds_timer();
+ return Py_BuildValue("d", t);
+}
+
diff --git a/source/blender/python/api2_2x/Sys.h b/source/blender/python/api2_2x/Sys.h
index f3967268129..446ac91490b 100644
--- a/source/blender/python/api2_2x/Sys.h
+++ b/source/blender/python/api2_2x/Sys.h
@@ -43,6 +43,7 @@
static PyObject *M_sys_basename (PyObject *self, PyObject *args);
static PyObject *M_sys_dirname (PyObject *self, PyObject *args);
static PyObject *M_sys_splitext (PyObject *self, PyObject *args);
+static PyObject *M_sys_time (PyObject *self);
/*****************************************************************************/
/* The following string definitions are used for documentation strings. */
@@ -65,6 +66,11 @@ static char M_sys_splitext_doc[]="(path) - Split 'path' in root and \
extension:\n/this/that/file.ext -> ('/this/that/file','.ext').\n\
Return the pair (root, extension).";
+static char M_sys_time_doc[]="() - Return a float representing time elapsed \
+in seconds.\n\
+Each successive call is garanteed to return values greater than or\n\
+equal to the previous call.";
+
/*****************************************************************************/
/* Python method structure definition for Blender.sys module: */
/*****************************************************************************/
@@ -72,6 +78,7 @@ struct PyMethodDef M_sys_methods[] = {
{"basename", M_sys_basename, METH_VARARGS, M_sys_basename_doc},
{"dirname", M_sys_dirname, METH_VARARGS, M_sys_dirname_doc},
{"splitext", M_sys_splitext, METH_VARARGS, M_sys_splitext_doc},
+ {"time", (PyCFunction)M_sys_time, METH_NOARGS, M_sys_time_doc},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/api2_2x/doc/Blender.py b/source/blender/python/api2_2x/doc/Blender.py
index d86607587f7..2bdd658a52f 100644
--- a/source/blender/python/api2_2x/doc/Blender.py
+++ b/source/blender/python/api2_2x/doc/Blender.py
@@ -29,6 +29,7 @@ The Blender Python API Reference
- L{Ipo}
- L{Lamp}
- L{Lattice}
+ - L{Library}
- L{Material}
- L{Mathutils}
- L{Metaball}
diff --git a/source/blender/python/api2_2x/doc/Library.py b/source/blender/python/api2_2x/doc/Library.py
new file mode 100644
index 00000000000..5f0f754dd78
--- /dev/null
+++ b/source/blender/python/api2_2x/doc/Library.py
@@ -0,0 +1,110 @@
+# Blender.Library submodule
+
+"""
+The Blender.Library submodule.
+
+Library
+=======
+
+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 is a new, still experimental module.
+
+Example::
+ import Blender
+ from Blender import Library
+
+ def f(name):
+ open_library(name)
+
+ def open_library(name):
+ Library.Open(name)
+ groups = Library.LinkableGroups()
+
+ for db in groups:
+ print "\nDATABLOCK %s:" % db
+ for obname in Library.Datablocks(db):
+ print obname
+
+ if 'Object' in groups:
+ for obname in Library.Datablocks('Object'):
+ Library.Load(obname, 'Object', 0) # note the 0...
+ Library.Update()
+
+ Library.Close()
+ b.Redraw()
+
+ b.Window.FileSelector(f, "Choose Library", "*.blend")
+
+"""
+
+def Open (filename):
+ """
+ Open an existing .blend file. If there was already one open file, it is
+ closed first.
+ @type filename: string
+ @param filename: The filename of a Blender file.
+ @rtype: bool
+ @return: 1 if succesful, 0 otherwise.
+ """
+
+def Close ():
+ """
+ Close the currently open library file, if any.
+ """
+
+def getName ():
+ """
+ Get the filename of the currently open library file.
+ @rtype: string
+ @return: The open library filename.
+ """
+
+def LinkableGroups ():
+ """
+ Get all the linkable group names from the currently open library file. These
+ are the available groups for linking with the current scene. Ex: 'Object',
+ 'Mesh', 'Material', 'Text', etc.
+ @rtype: list of strings
+ @return: the list of linkable groups.
+ """
+
+def Datablocks (group):
+ """
+ Get all datablock objects of the given 'group' available in the currently
+ open library file.
+ @type group: string
+ @param group: datablock group, see L{LinkableGroups}.
+ """
+
+def Load (datablock, group, update = 1):
+ """
+ Load the given datablock object from the current library file
+ @type datablock: string
+ @type group: string
+ @type update: bool
+ @param datablock: an available object name, as returned by L{Datablocks}.
+ @param group: an available group name, as returned by L{LinkableGroups}.
+ @param update: defines if Blender should be updated after loading this
+ object. This means linking all objects and remaking all display lists,
+ so it is potentially very slow.
+
+ @warn: If you plan to load more than one object in sequence, it is
+ B{definitely recommended} to set 'update' to 0 in all calls to this
+ function and after them call L{Update}.
+ """
+
+def Update ():
+ """
+ Update all links and display lists in Blender. This function should be
+ called after a series of L{Load}(datablock, group, B{0}) calls to make
+ everything behave nicely.
+ @warn: to use this function, remember to set the third L{Load} parameter to
+ zero or each loading will automatically update Blender, which will slow
+ down your script and make you look like a lousy programmer.
+ Enough warnings :)?
+ """
+
diff --git a/source/blender/python/api2_2x/doc/Sys.py b/source/blender/python/api2_2x/doc/Sys.py
index e212784d33c..d488c8a1f65 100644
--- a/source/blender/python/api2_2x/doc/Sys.py
+++ b/source/blender/python/api2_2x/doc/Sys.py
@@ -6,6 +6,8 @@ The Blender.sys submodule.
sys
===
+B{New}: L{time}
+
This module provides a minimal set of helper functions and data. Its purpose
is to avoid the need for the standard Python module 'os', in special 'os.path',
though it is only meant for the simplest cases.
@@ -63,3 +65,11 @@ def splitext (path):
@rtype: list with two strings
@return: (root, ext)
"""
+
+def time ():
+ """
+ Get the current time in seconds since a fixed value. Successive calls to
+ this function are garanteed to return values greater than the previous call.
+ @rtype: float
+ @return: the elapsed time in seconds.
+ """
diff --git a/source/blender/python/api2_2x/modules.h b/source/blender/python/api2_2x/modules.h
index 74f3ec81b5e..b78da5595eb 100644
--- a/source/blender/python/api2_2x/modules.h
+++ b/source/blender/python/api2_2x/modules.h
@@ -192,5 +192,6 @@ PyObject * Draw_Init (void);
PyObject * BGL_Init (void);
PyObject * Mathutils_Init (void);
PyObject * NLA_Init (void);
+PyObject * Library_Init (void);
#endif /* EXPP_modules_h */