BPython:
- local tentative fix for BLI_gethome(), which returns '.blender' appended only
on some Windows systems. Created bpymenu_gethome() to check and
add '.blender' if needed.
- changed name: .Bpymenus to Bpymenus as suggested by GSR
- trivial additions:
Object module: added methods .set/getSize
Armature/Bone module: bone.set???() methods now accept both n
floats or a list of n floats: fff or (fff). All these additions were requested
by user Carlos Lopez (Klopes).
- New doc: for module Registry.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -33,6 +33,7 @@ The Blender Python API Reference
|
||||
- L{Metaball}
|
||||
- L{NMesh}
|
||||
- L{Object}
|
||||
- L{Registry}
|
||||
- L{Scene}
|
||||
- L{Text}
|
||||
- L{Texture}
|
||||
|
||||
95
source/blender/python/api2_2x/doc/Registry.py
Normal file
95
source/blender/python/api2_2x/doc/Registry.py
Normal file
@@ -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.
|
||||
"""
|
||||
Reference in New Issue
Block a user