BPython:
authorWillian Padovani Germano <wpgermano@gmail.com>
Sat, 24 Apr 2004 20:04:37 +0000 (20:04 +0000)
committerWillian Padovani Germano <wpgermano@gmail.com>
Sat, 24 Apr 2004 20:04:37 +0000 (20:04 +0000)
- 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.

13 files changed:
source/blender/blenloader/BLO_readfile.h
source/blender/blenloader/intern/readfile.c
source/blender/python/SConscript
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/Blender.h
source/blender/python/api2_2x/Library.c [new file with mode: 0644]
source/blender/python/api2_2x/Makefile
source/blender/python/api2_2x/Sys.c
source/blender/python/api2_2x/Sys.h
source/blender/python/api2_2x/doc/Blender.py
source/blender/python/api2_2x/doc/Library.py [new file with mode: 0644]
source/blender/python/api2_2x/doc/Sys.py
source/blender/python/api2_2x/modules.h

index 66b3729d860ab876b565414e6cfd6dca4df1c6cf..3093160139b82a9630eafcafc02d81c1d4509df9 100644 (file)
@@ -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);
 
index 3ce03aca4a326ccb2bcd9e6c629597d3e4096e7d..6984f772c4229699fdfb8dbd7d8711c926d495f8 100644 (file)
@@ -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);
index 9377e45faf6a530d0f9161ff1687c645f5c48fe5..41fb4c082a26110cfd1a392313b2e29252622453 100644 (file)
@@ -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',
index 66d82c9509ce0a0235863f0d1ce7b1fa1d7fe70c..4671fed9e60afee79f67ed3b57362f3c24ebf88e 100644 (file)
@@ -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.
 #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());
 }
index 1241765163744abc28cd634c3d5247afdc963257..ebbae7ff63a01bafaf5e4cfaa08e0a7cdb84444d 100644 (file)
@@ -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 (file)
index 0000000..6a0a958
--- /dev/null
@@ -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;
+}
index cdefeee815d11b6e0bfa21e75e5545d6757bd297..545e5cb0875dee76c81eac75a584d9ff094601f3 100644 (file)
@@ -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
index 99b5d3488b536d4e15a687630f13d7022bef8b42..56f3a64d4897f69b2ada184e783e5cf8749a7b58 100644 (file)
@@ -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);
+}
+
index f3967268129e96cddaca69213d2a1424c808f2fc..446ac91490b2a7c646c383152eab415ceb5fc1f0 100644 (file)
@@ -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}
 };
 
index d86607587f7f613532f6adbd1a173dd5f7a6c884..2bdd658a52f46bad980d864108907d25429dcf3d 100644 (file)
@@ -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 (file)
index 0000000..5f0f754
--- /dev/null
@@ -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 :)?
+  """
+
index e212784d33c5f0921185ecdfe1e75ba03d86395b..d488c8a1f65899e356c8dd1f865f6e8a01197389 100644 (file)
@@ -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.
+  """
index 74f3ec81b5e5b087c900fcce71f9a4630fa6fa9b..b78da5595ebb91d00b7c97d0d1467e4ae025fea9 100644 (file)
@@ -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 */