Exppython:

- Window: added .GetCursorPos()
- Lamp: updated for NoDiffuse and NoSpecular modes
- Registry: new module to handle persistent data
- vector: made it correctly print only 3 values when vec->size==3:
    Fixes nmvert coords printed with a 4th 0.0 coordinate
- Text: fixed crash on startup (Python 2.3, linux):
    added definition of the Text pyobject earlier, in Types.c
This commit is contained in:
2003-09-03 04:13:08 +00:00
parent 65746ab10a
commit a09e5a7f2f
11 changed files with 330 additions and 17 deletions

View File

@@ -61,6 +61,11 @@
#include "BPY_extern.h"
#include "api2_2x/EXPP_interface.h"
/* bpy_registryDict is declared in api2_2x/Registry.h and defined
* here. This Python dictionary will be used to store data that scripts
* choose to preserve after they are executed, so user changes can be
* restored next time the script is used. Check the Blender.Registry module. */
extern PyObject *bpy_registryDict;
/*****************************************************************************/
/* Structure definitions */
@@ -96,6 +101,11 @@ PyObject *blender_import(PyObject *self, PyObject *args);
/*****************************************************************************/
void BPY_start_python(void)
{
bpy_registryDict = PyDict_New(); /* check comment at start of this file */
if (!bpy_registryDict)
printf("Error: Couldn't create the Registry Python Dictionary!");
/* TODO: Shouldn't "blender" be replaced by PACKAGE ?? (config.h) */
Py_SetProgramName("blender");
@@ -115,6 +125,11 @@ void BPY_start_python(void)
/*****************************************************************************/
void BPY_end_python(void)
{
if (bpy_registryDict) {
Py_DECREF (bpy_registryDict);
bpy_registryDict = NULL;
}
Py_Finalize();
return;
}

View File

@@ -208,6 +208,7 @@ void M_Blender_Init (void)
dict = PyModule_GetDict (module);
g_blenderdict = dict;
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, "Types", Types_Init());

View File

@@ -214,6 +214,10 @@ static PyObject *Lamp_ModesDict (void)
constant_insert (c, "Square", PyInt_FromLong (EXPP_LAMP_MODE_SQUARE));
constant_insert (c, "OnlyShadow",
PyInt_FromLong (EXPP_LAMP_MODE_ONLYSHADOW));
constant_insert (c, "NoDiffuse",
PyInt_FromLong (EXPP_LAMP_MODE_NODIFFUSE));
constant_insert (c, "NoSpecular",
PyInt_FromLong (EXPP_LAMP_MODE_NOSPECULAR));
}
return Modes;
@@ -559,15 +563,15 @@ static PyObject *Lamp_setIntType(BPy_Lamp *self, PyObject *args)
static PyObject *Lamp_setMode(BPy_Lamp *self, PyObject *args)
{
char *m[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
char *m[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
short i, flag = 0;
if (!PyArg_ParseTuple(args, "|ssssssss", &m[0], &m[1], &m[2],
&m[3], &m[4], &m[5], &m[6], &m[7]))
&m[3], &m[4], &m[5], &m[6], &m[7], &m[8], &m[9]))
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected from none to eight string argument(s)"));
"expected from none to 10 string argument(s)"));
for (i = 0; i < 8; i++) {
for (i = 0; i < 10; i++) {
if (m[i] == NULL) break;
if (strcmp(m[i], "Shadows") == 0)
flag |= (short)EXPP_LAMP_MODE_SHADOWS;
@@ -585,6 +589,10 @@ static PyObject *Lamp_setMode(BPy_Lamp *self, PyObject *args)
flag |= (short)EXPP_LAMP_MODE_SPHERE;
else if (strcmp(m[i], "Square") == 0)
flag |= (short)EXPP_LAMP_MODE_SQUARE;
else if (strcmp(m[i], "NoDiffuse") == 0)
flag |= (short)EXPP_LAMP_MODE_NODIFFUSE;
else if (strcmp(m[i], "NoSpecular") == 0)
flag |= (short)EXPP_LAMP_MODE_NOSPECULAR;
else
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"unknown lamp flag argument"));
@@ -924,7 +932,7 @@ static PyObject *Lamp_getAttr (BPy_Lamp *self, char *name)
}
else if (strcmp(name, "Modes") == 0) {
attr = Py_BuildValue("{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
attr = Py_BuildValue("{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
"Shadows", EXPP_LAMP_MODE_SHADOWS,
"Halo", EXPP_LAMP_MODE_HALO,
"Layer", EXPP_LAMP_MODE_LAYER,
@@ -932,7 +940,9 @@ static PyObject *Lamp_getAttr (BPy_Lamp *self, char *name)
"Negative", EXPP_LAMP_MODE_NEGATIVE,
"OnlyShadow", EXPP_LAMP_MODE_ONLYSHADOW,
"Sphere", EXPP_LAMP_MODE_SPHERE,
"Square", EXPP_LAMP_MODE_SQUARE);
"Square", EXPP_LAMP_MODE_SQUARE,
"NoDiffuse", EXPP_LAMP_MODE_NODIFFUSE,
"NoSpecular", EXPP_LAMP_MODE_NOSPECULAR);
}
else if (strcmp(name, "__members__") == 0) {

View File

@@ -72,7 +72,8 @@
#define EXPP_LAMP_MODE_TEXTURE 256
#define EXPP_LAMP_MODE_OSATEX 512
#define EXPP_LAMP_MODE_DEEPSHADOW 1024
#define EXPP_LAMP_MODE_NODIFFUSE 2048
#define EXPP_LAMP_MODE_NOSPECULAR 4096
/* Lamp MIN, MAX values */
#define EXPP_LAMP_SAMPLES_MIN 1

View File

@@ -0,0 +1,148 @@
/*
*
* ***** 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 "Registry.h"
/*****************************************************************************/
/* Function: M_Registry_Keys */
/* Python equivalent: Blender.Registry.Keys */
/*****************************************************************************/
PyObject *M_Registry_Keys (PyObject *self)
{
PyObject *pydict = NULL;
if (!bpy_registryDict)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"No Registry dictionary found!");
pydict = PyDict_Keys (bpy_registryDict);
if (!pydict)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Registry_Keys: couldn't get keys");
return pydict;
}
/*****************************************************************************/
/* Function: M_Registry_GetKey */
/* Python equivalent: Blender.Registry.GetKey */
/*****************************************************************************/
static PyObject *M_Registry_GetKey (PyObject *self, PyObject *args)
{
PyObject *pyentry = NULL;
PyObject *pydict = NULL;
if (!bpy_registryDict)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"No Registry dictionary found!");
if (!PyArg_ParseTuple (args, "O!", &PyString_Type, &pyentry))
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a string");
pydict = PyDict_GetItem (bpy_registryDict, pyentry); /* borrowed ... */
if (!pydict)
/* return EXPP_ReturnPyObjError (PyExc_KeyError,
"no such key in the Registry"); */
pydict = Py_None; /* better to return None than an error */
Py_INCREF (pydict); /* ... so we incref it */
/* should we copy the dict instead? */
return pydict;
}
/*****************************************************************************/
/* Function: M_Registry_SetKey */
/* Python equivalent: Blender.Registry.SetKey */
/*****************************************************************************/
static PyObject *M_Registry_SetKey (PyObject *self, PyObject *args)
{
PyObject *pystr = NULL;
PyObject *pydict = NULL;
if (!bpy_registryDict)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"No Registry dictionary found!");
if (!PyArg_ParseTuple (args, "O!O!",
&PyString_Type, &pystr, &PyDict_Type, &pydict))
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a string and a dictionary");
printf("dict size: %d", sizeof(*pydict)); /* debug XXX */
if (PyDict_SetItem (bpy_registryDict, pystr, pydict)) /* 0 on success */
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"Registry_SetKey: couldn't update the Registry dict");
Py_INCREF(Py_None);
return Py_None;
}
/*****************************************************************************/
/* Function: M_Registry_RemoveKey */
/* Python equivalent: Blender.Registry.RemoveKey */
/*****************************************************************************/
static PyObject *M_Registry_RemoveKey (PyObject *self, PyObject *args)
{
PyObject *pystr = NULL;
if (!bpy_registryDict)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"No Registry dictionary found!");
if (!PyArg_ParseTuple (args, "O!", &PyString_Type, &pystr))
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"expected a string");
if (PyDict_DelItem (bpy_registryDict, pystr)) /* returns 0 on success */
return EXPP_ReturnPyObjError (PyExc_KeyError,
"no such key in the Registry");
Py_INCREF (Py_None);
return Py_None;
}
/*****************************************************************************/
/* Function: Registry_Init */
/*****************************************************************************/
PyObject *Registry_Init (void)
{
PyObject *submodule;
submodule = Py_InitModule3("Blender.Registry", M_Registry_methods,
M_Registry_doc);
return submodule;
}

View File

@@ -0,0 +1,99 @@
/*
*
* ***** 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 *****
*/
/* This submodule was introduced as a way to preserve configured data in
* scripts. A very simple idea: the script writer saves this data in a dict
* and registers this dict in the "Registry" dict. This way we can discard
* the global interpreter dictionary after a script is executed, since the
* data meant to be kept was copied to the Registry elsewhere. The current
* implementation is naive: scripts can deliberately mess with data saved by
* other scripts. This is so new script versions can delete older entries, if
* they need to. XXX Or should we block this? */
#ifndef EXPP_REGISTRY_H
#define EXPP_REGISTRY_H
#include <Python.h>
#include <stdio.h>
#include "gen_utils.h"
#include "modules.h"
/* the Registry dictionary, declare here, defined in ../BPY_interface.c */
PyObject *bpy_registryDict = NULL;
/*****************************************************************************/
/* Python API function prototypes for the Registry module. */
/*****************************************************************************/
static PyObject *M_Registry_Keys (PyObject *self);
static PyObject *M_Registry_GetKey (PyObject *self, PyObject *args);
static PyObject *M_Registry_SetKey (PyObject *self, PyObject *args);
static PyObject *M_Registry_RemoveKey (PyObject *self, PyObject *args);
/*****************************************************************************/
/* The following string definitions are used for documentation strings. */
/* In Python these will be written to the console when doing a */
/* Blender.Registry.__doc__ */
/*****************************************************************************/
char M_Registry_doc[] =
"The Blender Registry module (persistent data cache)\n\n\
Use this module to store configuration data that a script can reload\n\
when it is executed again.\n";
char M_Registry_Keys_doc[] =
"() - Get all keys in the Registry dictionary.\n\n\
Each key references another dict with saved data from a specific script.\n";
char M_Registry_GetKey_doc[] =
"(name) - Get a specific entry (dict) from the Registry dictionary\n\
(name) - a string that references a specific script.\n";
char M_Registry_SetKey_doc[] =
"(key, dict) - Store an entry in the Registry dictionary.\n\
If an entry with the same 'key' already exists, it is substituted.\n\
(key) - the string to use as a key for the dict being saved.\n\
(dict) - a dictionary with the data to be stored.\n";
char M_Registry_RemoveKey_doc[] =
"(key) - Remove the dict with key 'key' from the Registry.\n";
/*****************************************************************************/
/* Python method structure definition for Blender.Registry module: */
/*****************************************************************************/
struct PyMethodDef M_Registry_methods[] = {
{"Keys", (PyCFunction)M_Registry_Keys, METH_VARARGS, M_Registry_Keys_doc},
{"GetKey", M_Registry_GetKey, METH_VARARGS, M_Registry_GetKey_doc},
{"SetKey", M_Registry_SetKey, METH_VARARGS, M_Registry_SetKey_doc},
{"RemoveKey", M_Registry_RemoveKey, METH_VARARGS, M_Registry_RemoveKey_doc},
{NULL, NULL, 0, NULL}
};
#endif /* EXPP_REGISTRY_H */

View File

@@ -50,6 +50,9 @@ PyObject *Types_Init (void)
buffer_Type.ob_type = &PyType_Type;
Button_Type.ob_type = &PyType_Type;
/* Another one that needs to be here: */
Text_Type.ob_type = &PyType_Type;
submodule = Py_InitModule3 ("Blender.Types", Null_methods, M_Types_doc);
dict = PyModule_GetDict(submodule);

View File

@@ -65,7 +65,7 @@ PyObject *M_Window_Redraw(PyObject *self, PyObject *args)
st = sa->spacedata.first;
if (st->text->flags & TXT_FOLLOW) /* follow cursor display */
pop_space_text(st);
if (EXPP_disable_force_draw) { /* from Draw.[ch] ... */
if (EXPP_disable_force_draw) { /* defined in Draw.[ch] ... */
scrarea_queue_redraw(sa);
}
@@ -123,26 +123,26 @@ static PyObject *M_Window_QRedrawAll(PyObject *self, PyObject *args)
static void getSelectedFile(char *name)
{
if (EXPP_FS_PyCallback) {
SpaceText *st= curarea->spacedata.first;
SpaceText *st= curarea->spacedata.first;
PyObject_CallFunction((PyObject *)EXPP_FS_PyCallback, "s", name);
EXPP_FS_PyCallback = NULL;
st->flags &= ST_CLEAR_NAMESPACE; /* free global dictionary */
EXPP_FS_PyCallback = NULL;
st->flags &= ST_CLEAR_NAMESPACE; /* global dict can be cleared */
}
}
static PyObject *M_Window_FileSelector(PyObject *self, PyObject *args)
{
char *title = "SELECT FILE";
SpaceText *st = curarea->spacedata.first;
SpaceText *st = curarea->spacedata.first;
if (!PyArg_ParseTuple(args, "O!|s",
&PyFunction_Type, &EXPP_FS_PyCallback, &title))
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"\nexpected a callback function (and optionally a string) as argument(s)"));
st->flags &= ~ST_CLEAR_NAMESPACE; /* hold global dictionary */
st->flags &= ~ST_CLEAR_NAMESPACE; /* so global dict won't be cleared */
activate_fileselect(FILE_BLENDER, title, G.sce, getSelectedFile);
@@ -153,14 +153,14 @@ static PyObject *M_Window_FileSelector(PyObject *self, PyObject *args)
static PyObject *M_Window_ImageSelector(PyObject *self, PyObject *args)
{
char *title = "SELECT IMAGE";
SpaceText *st = curarea->spacedata.first;
SpaceText *st = curarea->spacedata.first;
if (!PyArg_ParseTuple(args, "O!|s",
&PyFunction_Type, &EXPP_FS_PyCallback, &title))
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
"\nexpected a callback function (and optionally a string) as argument(s)"));
st->flags &= ~ST_CLEAR_NAMESPACE; /* hold global dictionary */
st->flags &= ~ST_CLEAR_NAMESPACE; /* hold global dictionary */
activate_imageselect(FILE_BLENDER, title, G.sce, getSelectedFile);
@@ -187,6 +187,28 @@ static PyObject *M_Window_DrawProgressBar(PyObject *self, PyObject *args)
return Py_BuildValue("i", retval);
}
/*****************************************************************************/
/* Function: M_Window_GetCursorPos */
/* Python equivalent: Blender.Window.GetCursorPos */
/*****************************************************************************/
static PyObject *M_Window_GetCursorPos(PyObject *self)
{
float *cursor = NULL;
PyObject *pylist;
if (G.vd && G.vd->localview)
cursor = G.vd->cursor;
else cursor = G.scene->cursor;
pylist = Py_BuildValue("[fff]", cursor[0], cursor[1], cursor[2]);
if (!pylist)
return (EXPP_ReturnPyObjError (PyExc_MemoryError,
"GetCursorPos: couldn't create pylist"));
return pylist;
}
/*****************************************************************************/
/* Function: Window_Init */
/*****************************************************************************/

View File

@@ -68,6 +68,7 @@ static PyObject *M_Window_QRedrawAll (PyObject *self, PyObject *args);
static PyObject *M_Window_FileSelector (PyObject *self, PyObject *args);
static PyObject *M_Window_ImageSelector (PyObject *self, PyObject *args);
static PyObject *M_Window_DrawProgressBar (PyObject *self, PyObject *args);
static PyObject *M_Window_GetCursorPos (PyObject *self);
/*****************************************************************************/
/* The following string definitions are used for documentation strings. */
@@ -111,6 +112,9 @@ char M_Window_DrawProgressBar_doc[] =
'done' is a float value <= 1.0, 'text' contains info about what is\n\
currently being done.";
char M_Window_GetCursorPos_doc[] =
"() - Get the current 3d cursor position as a list of three floats.";
/*****************************************************************************/
/* Python method structure definition for Blender.Window module: */
/*****************************************************************************/
@@ -118,13 +122,16 @@ struct PyMethodDef M_Window_methods[] = {
{"Redraw", M_Window_Redraw, METH_VARARGS, M_Window_Redraw_doc},
{"RedrawAll", M_Window_RedrawAll, METH_VARARGS, M_Window_RedrawAll_doc},
{"QRedrawAll", M_Window_QRedrawAll, METH_VARARGS, M_Window_QRedrawAll_doc},
{"FileSelector", M_Window_FileSelector, METH_VARARGS, M_Window_FileSelector_doc},
{"FileSelector", M_Window_FileSelector, METH_VARARGS,
M_Window_FileSelector_doc},
{"ImageSelector", M_Window_ImageSelector, METH_VARARGS,
M_Window_ImageSelector_doc},
{"DrawProgressBar", M_Window_DrawProgressBar, METH_VARARGS,
M_Window_DrawProgressBar_doc},
{"drawProgressBar", M_Window_DrawProgressBar, METH_VARARGS,
M_Window_DrawProgressBar_doc},
{"GetCursorPos", (PyCFunction)M_Window_GetCursorPos, METH_NOARGS,
M_Window_GetCursorPos_doc},
{NULL, NULL, 0, NULL}
};

View File

@@ -63,6 +63,9 @@ void M_Blender_Init (void);
/* sys */
PyObject * sys_Init (void);
/* Registry */
PyObject * Registry_Init (void);
/* Object itself */
PyObject * Object_Init (void);
PyObject * Object_CreatePyObject (struct Object *obj);

View File

@@ -148,7 +148,11 @@ static PyObject *Vector_repr (VectorObject *self)
{
char buffer[100];
sprintf (buffer, "[%.3f, %.3f, %.3f, %.3f]\n",
if (self->size == 3)
sprintf (buffer, "[%.3f, %.3f, %.3f]\n",
self->vec[0], self->vec[1], self->vec[2]);
else /* assuming size == 4 */
sprintf (buffer, "[%.3f, %.3f, %.3f, %.3f]\n",
self->vec[0], self->vec[1], self->vec[2], self->vec[3]);
return PyString_FromString (buffer);