Skip to content
Snippets Groups Projects
Commit 5d8c7e45 authored by Willian Padovani Germano's avatar Willian Padovani Germano
Browse files

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.
parent f237bb28
Branches
Tags
No related merge requests found
......@@ -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}
......
# 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.
"""
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment