diff options
-rw-r--r-- | source/blender/python/BPY_menus.c | 34 | ||||
-rw-r--r-- | source/blender/python/BPY_menus.h | 2 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Bone.c | 73 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Object.c | 46 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Blender.py | 1 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Registry.py | 95 |
6 files changed, 221 insertions, 30 deletions
diff --git a/source/blender/python/BPY_menus.c b/source/blender/python/BPY_menus.c index 43eae8c49a6..070b32557a7 100644 --- a/source/blender/python/BPY_menus.c +++ b/source/blender/python/BPY_menus.c @@ -63,7 +63,29 @@ #include <errno.h> -#define BPYMENU_DATAFILE ".Bpymenus" +#define BPYMENU_DATAFILE "Bpymenus" + +/* BPyMenuTable holds all registered pymenus, as linked lists for each menu + * where they can appear (see PYMENUHOOKS enum in BPY_menus.h). +*/ +BPyMenu *BPyMenuTable[PYMENU_TOTAL]; + +/* we can't be sure if BLI_gethome() returned a path + * with '.blender' appended or not, so: */ +static char *bpymenu_gethome() +{ + static char homedir[FILE_MAXDIR]; + char *s; + + if (homedir[0] != '\0') return homedir; + + s = BLI_gethome(); + + if (strstr(s, ".blender")) PyOS_snprintf(homedir, FILE_MAXDIR, s); + else BLI_make_file_string ("/", homedir, s, ".blender/"); + + return homedir; +} static int bpymenu_group_atoi (char *str) { @@ -282,7 +304,7 @@ static int bpymenu_CreateFromFile (void) BPyMenuTable[group] = NULL; /* let's try to open the file with bpymenu data */ - BLI_make_file_string ("/", line, BLI_gethome(),"/.blender/"BPYMENU_DATAFILE); + BLI_make_file_string ("/", line, bpymenu_gethome(), BPYMENU_DATAFILE); fp = fopen(line, "rb"); @@ -369,7 +391,7 @@ static void bpymenu_WriteDataFile(void) char fname[FILE_MAXDIR+FILE_MAXFILE]; int i; - BLI_make_file_string("/", fname, BLI_gethome(), ".blender/"BPYMENU_DATAFILE); + BLI_make_file_string("/", fname, bpymenu_gethome(), BPYMENU_DATAFILE); fp = fopen(fname, "w"); if (!fp) { @@ -595,7 +617,7 @@ static int bpymenu_GetStatMTime(char *name, int is_file, time_t* mtime) /* BPyMenu_Init: * import the bpython menus data to Blender, either from: - * - the BPYMENU_DATAFILE file (~/.Bpymenus) or + * - the BPYMENU_DATAFILE file (~/Bpymenus) or * - the scripts dir(s), case newer than the datafile (then update the file). * then fill the bpymenu table with this data. * if param usedir != 0, then the data is recreated from the dir(s) anyway. @@ -615,7 +637,7 @@ int BPyMenu_Init(int usedir) if (U.pythondir[0] == '\0') upydir = NULL; - BLI_make_file_string ("/", dirname, BLI_gethome(), ".blender/scripts/"); + BLI_make_file_string ("/", dirname, bpymenu_gethome(), "scripts/"); res1 = bpymenu_GetStatMTime(dirname, 0, &tdir1); @@ -652,7 +674,7 @@ int BPyMenu_Init(int usedir) printf("\nRegistering scripts in Blender menus ...\n\n"); if (!usedir) { /* if we're not forced to use the dir */ - BLI_make_file_string("/", fname, BLI_gethome(),".blender/"BPYMENU_DATAFILE); + BLI_make_file_string("/", fname, bpymenu_gethome(), BPYMENU_DATAFILE); resf = bpymenu_GetStatMTime(fname, 1, &tfile); if (resf < 0) tfile = 0; } diff --git a/source/blender/python/BPY_menus.h b/source/blender/python/BPY_menus.h index ffeee746b8a..682aa929f86 100644 --- a/source/blender/python/BPY_menus.h +++ b/source/blender/python/BPY_menus.h @@ -88,7 +88,7 @@ typedef enum { /* BPyMenuTable holds all registered pymenus, as linked lists for each menu * where they can appear (see PYMENUHOOKS enum above). */ -BPyMenu *BPyMenuTable[PYMENU_TOTAL]; +extern BPyMenu *BPyMenuTable[]; /* defined in BPY_menus.c */ /* public functions: */ int BPyMenu_Init(int usedir); diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c index c0dade51140..94ce51cf275 100644 --- a/source/blender/python/api2_2x/Bone.c +++ b/source/blender/python/api2_2x/Bone.c @@ -455,14 +455,20 @@ PyObject *Bone_setRoll(BPy_Bone *self, PyObject *args) static PyObject *Bone_setHead(BPy_Bone *self, PyObject *args) { float f1,f2,f3; + int status; if (!self->bone) (EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't get attribute from a NULL bone")); - - if (!PyArg_ParseTuple(args, "fff", &f1,&f2,&f3)) + + if (PyObject_Length (args) == 3) + status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3); + else + status = PyArg_ParseTuple (args, "(fff)", &f1, &f2, &f3); + + if (!status) return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected 3 float arguments")); - + "expected 3 (or a list of 3) float arguments")); + self->bone->head[0] = f1; self->bone->head[1] = f2; self->bone->head[2] = f3; @@ -475,14 +481,20 @@ static PyObject *Bone_setHead(BPy_Bone *self, PyObject *args) static PyObject *Bone_setTail(BPy_Bone *self, PyObject *args) { float f1,f2,f3; + int status; if (!self->bone) (EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't get attribute from a NULL bone")); - - if (!PyArg_ParseTuple(args, "fff", &f1,&f2,&f3)) + + if (PyObject_Length (args) == 3) + status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3); + else + status = PyArg_ParseTuple (args, "(fff)", &f1, &f2, &f3); + + if (!status) return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected 3 float arguments")); - + "expected 3 (or a list of 3) float arguments")); + self->bone->tail[0] = f1; self->bone->tail[1] = f2; self->bone->tail[2] = f3; @@ -495,14 +507,20 @@ static PyObject *Bone_setTail(BPy_Bone *self, PyObject *args) static PyObject *Bone_setLoc(BPy_Bone *self, PyObject *args) { float f1,f2,f3; + int status; if (!self->bone) (EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't get attribute from a NULL bone")); - - if (!PyArg_ParseTuple(args, "fff", &f1,&f2,&f3)) + + if (PyObject_Length (args) == 3) + status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3); + else + status = PyArg_ParseTuple (args, "(fff)", &f1, &f2, &f3); + + if (!status) return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected 3 float arguments")); - + "expected 3 (or a list of 3) float arguments")); + self->bone->loc[0] = f1; self->bone->loc[1] = f2; self->bone->loc[2] = f3; @@ -515,14 +533,20 @@ static PyObject *Bone_setLoc(BPy_Bone *self, PyObject *args) static PyObject *Bone_setSize(BPy_Bone *self, PyObject *args) { float f1,f2,f3; + int status; if (!self->bone) (EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't get attribute from a NULL bone")); - - if (!PyArg_ParseTuple(args, "fff", &f1,&f2,&f3)) + + if (PyObject_Length (args) == 3) + status = PyArg_ParseTuple (args, "fff", &f1, &f2, &f3); + else + status = PyArg_ParseTuple (args, "(fff)", &f1, &f2, &f3); + + if (!status) return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected 3 float arguments")); - + "expected 3 (or a list of 3) float arguments")); + self->bone->size[0] = f1; self->bone->size[1] = f2; self->bone->size[2] = f3; @@ -535,14 +559,20 @@ static PyObject *Bone_setSize(BPy_Bone *self, PyObject *args) static PyObject *Bone_setQuat(BPy_Bone *self, PyObject *args) { float f1,f2,f3,f4; + int status; if (!self->bone) (EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't get attribute from a NULL bone")); - - if (!PyArg_ParseTuple(args, "ffff", &f1,&f2,&f3,&f4)) + + if (PyObject_Length (args) == 4) + status = PyArg_ParseTuple (args, "ffff", &f1, &f2, &f3, &f4); + else + status = PyArg_ParseTuple (args, "(ffff)", &f1, &f2, &f3, &f4); + + if (!status) return (EXPP_ReturnPyObjError (PyExc_AttributeError, - "expected 4 float arguments")); - + "expected 4 (or a list of 4) float arguments")); + self->bone->quat[0] = f1; self->bone->quat[1] = f2; self->bone->quat[2] = f3; @@ -552,7 +582,6 @@ static PyObject *Bone_setQuat(BPy_Bone *self, PyObject *args) return Py_None; } - /*****************************************************************************/ /* Function: Bone_dealloc */ /* Description: This is a callback function for the BPy_Bone type. It is */ @@ -707,7 +736,7 @@ int Bone_CheckPyObject (PyObject *py_obj) /*****************************************************************************/ struct Bone* Bone_FromPyObject (PyObject *py_obj) { - BPy_Bone * blen_obj; + BPy_Bone * blen_obj; blen_obj = (BPy_Bone*)py_obj; return (blen_obj->bone); diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 90ea1924309..38e8e25f6ae 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -101,6 +101,7 @@ static PyObject *Object_getMaterials (BPy_Object *self); static PyObject *Object_getMatrix (BPy_Object *self); static PyObject *Object_getName (BPy_Object *self); static PyObject *Object_getParent (BPy_Object *self); +static PyObject *Object_getSize (BPy_Object *self, PyObject *args); static PyObject *Object_getTracked (BPy_Object *self); static PyObject *Object_getType (BPy_Object *self); static PyObject *Object_getBoundBox (BPy_Object *self); @@ -116,6 +117,7 @@ static PyObject *Object_setIpo (BPy_Object *self, PyObject *args); static PyObject *Object_setLocation (BPy_Object *self, PyObject *args); static PyObject *Object_setMaterials (BPy_Object *self, PyObject *args); static PyObject *Object_setName (BPy_Object *self, PyObject *args); +static PyObject *Object_setSize (BPy_Object *self, PyObject *args); static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args); /*****************************************************************************/ @@ -154,6 +156,8 @@ hierarchy (faster)"}, "Returns the name of the object"}, {"getParent", (PyCFunction)Object_getParent, METH_NOARGS, "Returns the object's parent object"}, + {"getSize", (PyCFunction)Object_getSize, METH_VARARGS, + "Returns the object's size (x, y, z)"}, {"getTracked", (PyCFunction)Object_getTracked, METH_NOARGS, "Returns the object's tracked object"}, {"getType", (PyCFunction)Object_getType, METH_NOARGS, @@ -175,7 +179,7 @@ fase:\n\t0: update scene hierarchy automatically\n\t\ don't update scene hierarchy (faster). In this case, you must\n\t\ explicitely update the Scene hierarchy."}, {"materialUsage", (PyCFunction)Object_materialUsage, METH_VARARGS, - "Determines the way the material is used and returs status.\n\ + "Determines the way the material is used and returns status.\n\ Possible arguments (provide as strings):\n\ \tData: Materials assigned to the object's data are shown. (default)\n\ \tObject: Materials assigned to the object are shown."}, @@ -198,6 +202,9 @@ triple."}, objects."}, {"setName", (PyCFunction)Object_setName, METH_VARARGS, "Sets the name of the object"}, + {"setSize", (PyCFunction)Object_setSize, METH_VARARGS, + "Set the object's size. The first argument must be a vector\n\ +triple."}, {"shareFrom", (PyCFunction)Object_shareFrom, METH_VARARGS, "Link data of self with object specified in the argument. This\n\ works only if self and the object specified are of the same type."}, @@ -814,6 +821,19 @@ static PyObject *Object_getParent (BPy_Object *self) "couldn't get Object.parent attribute")); } +static PyObject *Object_getSize (BPy_Object *self, PyObject *args) +{ + PyObject *attr = Py_BuildValue ("fff", + self->object->size[0], + self->object->size[1], + self->object->size[2]); + + if (attr) return (attr); + + return (PythonReturnErrorObject (PyExc_RuntimeError, + "couldn't get Object.size attributes")); +} + static PyObject *Object_getTracked (BPy_Object *self) { PyObject *attr; @@ -1302,6 +1322,30 @@ static PyObject *Object_setName (BPy_Object *self, PyObject *args) return (Py_None); } +static PyObject *Object_setSize (BPy_Object *self, PyObject *args) +{ + float sizex; + float sizey; + float sizez; + int status; + + if (PyObject_Length (args) == 3) + status = PyArg_ParseTuple (args, "fff", &sizex, &sizey, &sizez); + else + status = PyArg_ParseTuple (args, "(fff)", &sizex, &sizey, &sizez); + + if (!status) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected list argument of 3 floats"); + + self->object->size[0] = sizex; + self->object->size[1] = sizey; + self->object->size[2] = sizez; + + Py_INCREF (Py_None); + return (Py_None); +} + static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args) { BPy_Object * object; diff --git a/source/blender/python/api2_2x/doc/Blender.py b/source/blender/python/api2_2x/doc/Blender.py index c72c9eb0331..cc03ef5b3f1 100644 --- a/source/blender/python/api2_2x/doc/Blender.py +++ b/source/blender/python/api2_2x/doc/Blender.py @@ -33,6 +33,7 @@ The Blender Python API Reference - L{Metaball} - L{NMesh} - L{Object} + - L{Registry} - L{Scene} - L{Text} - L{Texture} diff --git a/source/blender/python/api2_2x/doc/Registry.py b/source/blender/python/api2_2x/doc/Registry.py new file mode 100644 index 00000000000..c7e981a69d0 --- /dev/null +++ b/source/blender/python/api2_2x/doc/Registry.py @@ -0,0 +1,95 @@ +# Blender.Registry module + +""" +The Blender.Registry submodule. + +Registry +======== + +This module provides a way to create, retrieve and edit B{persistent data} in +Blender. When a script runs in Blender, it has its own private global +dictionary, which is deleted when the script finishes. This is done to avoid +problems with name clashes and garbage collecting. But the result is that +data created by a script isn't kept after it leaves, for itself or others to +access later: the data isn't persistent. The Registry module was created to +give script authors a way around this limitation. In Python terms, the +Registry holds a dictionary of dictionaries. + +You should use it to save Python objects only, not BPython (Blender Python) +objects -- but you can save BPython object names, since those are strings. +Also, if you need to save a considerable amount of data, please save to a +file instead. There's no need to keep huge blocks of memory around when they +can simply be read from a file. + +Two uses for this module: + +a) Save configuration data from your script's gui (button values) so that the +next time the user runs your script, the changes will still be there. Later we +can make Blender save the Registry so that its data won't be lost after users +quit the program. And also add an option to save as a Text that can be kept in +a .blend file, letting users keep script data there. + +b) Save data from a script that another one will need to access later. + +Example:: + + import Blender + from Blender import Registry + + # first declare your global variables: + myvar1 = 0 + myvar2 = 3.2 + mystr = "hello" + # + # then check if they are already at the Registry (saved on a + # previous execution of your script): + dict = Registry.GetKey('MyScript') + if dict: # if found, get the values saved there + myvar1 = dict['myvar1'] + myvar2 = dict['myvar2'] + mystr = dict['mystr'] + # + # let's create a function to update the Registry when we need to: + def update_Registry(): + d = {} + d['myvar1'] = myvar1 + d['myvar2'] = myvar2 + d['mystr'] = mystr + Blender.Registry.SetKey('MyScript', d) + # ... + # here goes the main part of your script ... + # ... + # at the end, before exiting, we use our helper function: + update_Registry() + # note1: better not update the Registry when the user cancels the script + # note2: most scripts shouldn't need to register more than one key. +""" + +def Keys (): + """ + Get all keys currently in the Registry's dictionary. + """ + +def GetKey (key): + """ + Get key 'key' from the Registry. + @type key: string + @param key: a key from the Registry dictionary. + @return: the dictionary called 'key'. + """ + +def SetKey (key, dict): + """ + Store a new entry in the Registry. + @type key: string + @param key: the name of the new entry, tipically your script's name. + @type dict: dictionary + @param dict: a dict with all data you want to save in the Registry. + """ + +def RemoveKey (key): + """ + Remove the dictionary with key 'key' from the Registry. + @type key: string + @param key: the name of an existing Registry key. + """ |