Merged changes in the trunk up to revision 31190.

This commit is contained in:
2010-08-09 11:32:55 +00:00
520 changed files with 17532 additions and 19845 deletions

View File

@@ -11,6 +11,9 @@ incs += ' ' + env['BF_PYTHON_INC']
defs = []
if env['BF_BUILDINFO']:
defs.append('BUILD_DATE')
if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG']:
defs.append('_DEBUG')

View File

@@ -367,6 +367,7 @@ def rna2sphinx(BASEPATH):
# py modules
fw(" bpy.utils.rst\n\n")
fw(" bpy.path.rst\n\n")
fw(" bpy.app.rst\n\n")
# C modules
@@ -448,6 +449,9 @@ def rna2sphinx(BASEPATH):
from bpy import utils as module
pymodule2sphinx(BASEPATH, "bpy.utils", module, "Utilities (bpy.utils)")
from bpy import path as module
pymodule2sphinx(BASEPATH, "bpy.path", module, "Path Utilities (bpy.path)")
# C modules
from bpy import app as module
pymodule2sphinx(BASEPATH, "bpy.app", module, "Application Data (bpy.app)")

View File

@@ -350,3 +350,26 @@ void bpy_text_clear_modules(int clear_all)
Py_DECREF(list); /* removes all references from append */
}
#endif
/*****************************************************************************
* Description: This function creates a new Python dictionary object.
* note: dict is owned by sys.modules["__main__"] module, reference is borrowed
* note: important we use the dict from __main__, this is what python expects
for 'pickle' to work as well as strings like this...
>> foo = 10
>> print(__import__("__main__").foo)
*****************************************************************************/
PyObject *bpy_namespace_dict_new(const char *filename)
{
PyInterpreterState *interp= PyThreadState_GET()->interp;
PyObject *mod_main= PyModule_New("__main__");
PyDict_SetItemString(interp->modules, "__main__", mod_main);
Py_DECREF(mod_main); /* sys.modules owns now */
PyModule_AddStringConstant(mod_main, "__name__", "__main__");
if(filename)
PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */
PyModule_AddObject(mod_main, "__builtins__", interp->builtins);
Py_INCREF(interp->builtins); /* AddObject steals a reference */
return PyModule_GetDict(mod_main);
}

View File

@@ -60,5 +60,7 @@ extern PyMethodDef bpy_reload_meth[];
struct Main *bpy_import_main_get(void);
void bpy_import_main_set(struct Main *maggie);
/* name namespace function for bpy & bge */
PyObject *bpy_namespace_dict_new(const char *filename);
#endif /* EXPP_bpy_import_h */

View File

@@ -44,6 +44,7 @@
* - toEuler --> to_euler
* - toQuat --> to_quat
* - Vector.toTrackQuat --> Vector.to_track_quat
* - Quaternion * Quaternion --> cross product (not dot product)
*
* Moved to Geometry module: Intersect, TriangleArea, TriangleNormal, QuadNormal, LineIntersect
*/
@@ -92,74 +93,6 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
return size;
}
//-----------------------------METHODS----------------------------
//-----------------quat_rotation (internal)-----------
//This function multiplies a vector/point * quat or vice versa
//to rotate the point/vector by the quaternion
//arguments should all be 3D
PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
{
float rot[3];
QuaternionObject *quat = NULL;
VectorObject *vec = NULL;
if(QuaternionObject_Check(arg1)){
quat = (QuaternionObject*)arg1;
if(!BaseMath_ReadCallback(quat))
return NULL;
if(VectorObject_Check(arg2)){
vec = (VectorObject*)arg2;
if(!BaseMath_ReadCallback(vec))
return NULL;
rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] -
2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] +
2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] -
quat->quat[3]*quat->quat[3]*vec->vec[0] - quat->quat[2]*quat->quat[2]*vec->vec[0];
rot[1] = 2*quat->quat[1]*quat->quat[2]*vec->vec[0] + quat->quat[2]*quat->quat[2]*vec->vec[1] +
2*quat->quat[3]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[3]*vec->vec[0] -
quat->quat[3]*quat->quat[3]*vec->vec[1] + quat->quat[0]*quat->quat[0]*vec->vec[1] -
2*quat->quat[1]*quat->quat[0]*vec->vec[2] - quat->quat[1]*quat->quat[1]*vec->vec[1];
rot[2] = 2*quat->quat[1]*quat->quat[3]*vec->vec[0] + 2*quat->quat[2]*quat->quat[3]*vec->vec[1] +
quat->quat[3]*quat->quat[3]*vec->vec[2] - 2*quat->quat[0]*quat->quat[2]*vec->vec[0] -
quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] -
quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2];
return newVectorObject(rot, 3, Py_NEW, NULL);
}
}else if(VectorObject_Check(arg1)){
vec = (VectorObject*)arg1;
if(!BaseMath_ReadCallback(vec))
return NULL;
if(QuaternionObject_Check(arg2)){
quat = (QuaternionObject*)arg2;
if(!BaseMath_ReadCallback(quat))
return NULL;
rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] -
2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] +
2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] -
quat->quat[3]*quat->quat[3]*vec->vec[0] - quat->quat[2]*quat->quat[2]*vec->vec[0];
rot[1] = 2*quat->quat[1]*quat->quat[2]*vec->vec[0] + quat->quat[2]*quat->quat[2]*vec->vec[1] +
2*quat->quat[3]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[3]*vec->vec[0] -
quat->quat[3]*quat->quat[3]*vec->vec[1] + quat->quat[0]*quat->quat[0]*vec->vec[1] -
2*quat->quat[1]*quat->quat[0]*vec->vec[2] - quat->quat[1]*quat->quat[1]*vec->vec[1];
rot[2] = 2*quat->quat[1]*quat->quat[3]*vec->vec[0] + 2*quat->quat[2]*quat->quat[3]*vec->vec[1] +
quat->quat[3]*quat->quat[3]*vec->vec[2] - 2*quat->quat[0]*quat->quat[2]*vec->vec[0] -
quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] -
quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2];
return newVectorObject(rot, 3, Py_NEW, NULL);
}
}
PyErr_SetString(PyExc_RuntimeError, "quat_rotation(internal): internal problem rotating vector/point\n");
return NULL;
}
//----------------------------------MATRIX FUNCTIONS--------------------
//----------------------------------mathutils.RotationMatrix() ----------
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
@@ -696,7 +629,7 @@ PyObject *BaseMathObject_getOwner( BaseMathObject * self, void *type )
return ret;
}
char BaseMathObject_Wrapped_doc[] = "True when this object wraps external data (readonly). **type** boolean";
char BaseMathObject_Wrapped_doc[] = "True when this object wraps external data (readonly).\n\n:type: boolean";
PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void *type )
{
return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0);

View File

@@ -63,8 +63,6 @@ void BaseMathObject_dealloc(BaseMathObject * self);
PyObject *Mathutils_Init(void);
PyObject *Noise_Init(void); /* lazy, saves having own header */
PyObject *quat_rotation(PyObject *arg1, PyObject *arg2);
int EXPP_FloatsAreEqual(float A, float B, int floatSteps);
int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps);

View File

@@ -434,15 +434,15 @@ static int Color_setHSV(ColorObject * self, PyObject * value, void * type)
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Color_getseters[] = {
{"r", (getter)Color_getChannel, (setter)Color_setChannel, "Red color channel. **type** float", (void *)0},
{"g", (getter)Color_getChannel, (setter)Color_setChannel, "Green color channel. **type** float", (void *)1},
{"b", (getter)Color_getChannel, (setter)Color_setChannel, "Blue color channel. **type** float", (void *)2},
{"r", (getter)Color_getChannel, (setter)Color_setChannel, "Red color channel.\n\n:type: float", (void *)0},
{"g", (getter)Color_getChannel, (setter)Color_setChannel, "Green color channel.\n\n:type: float", (void *)1},
{"b", (getter)Color_getChannel, (setter)Color_setChannel, "Blue color channel.\n\n:type: float", (void *)2},
{"h", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Hue component in [0, 1]. **type** float", (void *)0},
{"s", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Saturation component in [0, 1]. **type** float", (void *)1},
{"v", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Value component in [0, 1]. **type** float", (void *)2},
{"h", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Hue component in [0, 1].\n\n:type: float", (void *)0},
{"s", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Saturation component in [0, 1].\n\n:type: float", (void *)1},
{"v", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Value component in [0, 1].\n\n:type: float", (void *)2},
{"hsv", (getter)Color_getHSV, (setter)Color_setHSV, "HSV Values in [0, 1]. **type** float triplet", (void *)0},
{"hsv", (getter)Color_getHSV, (setter)Color_setHSV, "HSV Values in [0, 1].\n\n:type: float triplet", (void *)0},
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
{"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},

View File

@@ -615,10 +615,10 @@ static int Euler_setOrder( EulerObject * self, PyObject * value, void * type )
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Euler_getseters[] = {
{"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis in radians. **type** float", (void *)0},
{"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis in radians. **type** float", (void *)1},
{"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis in radians. **type** float", (void *)2},
{"order", (getter)Euler_getOrder, (setter)Euler_setOrder, "Euler rotation order. **type** string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']", (void *)NULL},
{"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis in radians.\n\n:type: float", (void *)0},
{"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis in radians.\n\n:type: float", (void *)1},
{"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis in radians.\n\n:type: float", (void *)2},
{"order", (getter)Euler_getOrder, (setter)Euler_setOrder, "Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']", (void *)NULL},
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
{"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},

View File

@@ -1300,10 +1300,10 @@ static PyObject *Matrix_getIsNegative( MatrixObject * self, void *type )
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Matrix_getseters[] = {
{"row_size", (getter)Matrix_getRowSize, (setter)NULL, "The row size of the matrix (readonly). **type** int", NULL},
{"col_size", (getter)Matrix_getColSize, (setter)NULL, "The column size of the matrix (readonly). **type** int", NULL},
{"median_scale", (getter)Matrix_getMedianScale, (setter)NULL, "The average scale applied to each axis (readonly). **type** float", NULL},
{"is_negative", (getter)Matrix_getIsNegative, (setter)NULL, "True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly). **type** bool", NULL},
{"row_size", (getter)Matrix_getRowSize, (setter)NULL, "The row size of the matrix (readonly).\n\n:type: int", NULL},
{"col_size", (getter)Matrix_getColSize, (setter)NULL, "The column size of the matrix (readonly).\n\n:type: int", NULL},
{"median_scale", (getter)Matrix_getMedianScale, (setter)NULL, "The average scale applied to each axis (readonly).\n\n:type: float", NULL},
{"is_negative", (getter)Matrix_getIsNegative, (setter)NULL, "True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL},
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
{"_owner",(getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */

View File

@@ -660,8 +660,9 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
return NULL;
}
if(quat1 && quat2) { /* QUAT*QUAT (dot product) */
return PyFloat_FromDouble(dot_qtqt(quat1->quat, quat2->quat));
if(quat1 && quat2) { /* QUAT*QUAT (cross product) */
mul_qt_qtqt(quat, quat1->quat, quat2->quat);
return newQuaternionObject(quat, Py_NEW, NULL);
}
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
@@ -677,12 +678,19 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
}
else { /* QUAT*SOMETHING */
if(VectorObject_Check(q2)){ /* QUAT*VEC */
float tvec[3];
vec = (VectorObject*)q2;
if(vec->size != 3){
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n");
return NULL;
}
return quat_rotation((PyObject*)quat1, (PyObject*)vec); /* vector updating done inside the func */
if(!BaseMath_ReadCallback(vec)) {
return NULL;
}
copy_v3_v3(tvec, vec->vec);
mul_qt_v3(quat1->quat, tvec);
return newVectorObject(tvec, 3, Py_NEW, NULL);
}
scalar= PyFloat_AsDouble(q2);
@@ -914,13 +922,13 @@ static struct PyMethodDef Quaternion_methods[] = {
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Quaternion_getseters[] = {
{"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion W value. **type** float", (void *)0},
{"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion X axis. **type** float", (void *)1},
{"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Y axis. **type** float", (void *)2},
{"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Z axis. **type** float", (void *)3},
{"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, "Size of the quaternion (readonly). **type** float", NULL},
{"angle", (getter)Quaternion_getAngle, (setter)Quaternion_setAngle, "angle of the quaternion. **type** float", NULL},
{"axis",(getter)Quaternion_getAxisVec, (setter)Quaternion_setAxisVec, "quaternion axis as a vector. **type** :class:`Vector`", NULL},
{"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion W value.\n\n:type: float", (void *)0},
{"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion X axis.\n\n:type: float", (void *)1},
{"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Y axis.\n\n:type: float", (void *)2},
{"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Z axis.\n\n:type: float", (void *)3},
{"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, "Size of the quaternion (readonly).\n\n:type: float", NULL},
{"angle", (getter)Quaternion_getAngle, (setter)Quaternion_setAngle, "angle of the quaternion.\n\n:type: float", NULL},
{"axis",(getter)Quaternion_getAxisVec, (setter)Quaternion_setAxisVec, "quaternion axis as a vector.\n\n:type: :class:`Vector`", NULL},
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
{"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */

View File

@@ -1010,13 +1010,20 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
/* VEC * MATRIX */
return row_vector_multiplication(vec1, (MatrixObject*)v2);
} else if (QuaternionObject_Check(v2)) {
QuaternionObject *quat = (QuaternionObject*)v2; /* quat_rotation validates */
/* VEC * QUAT */
QuaternionObject *quat2 = (QuaternionObject*)v2;
float tvec[4];
if(vec1->size != 3) {
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
return NULL;
}
return quat_rotation((PyObject*)vec1, (PyObject*)quat);
if(!BaseMath_ReadCallback(quat2)) {
return NULL;
}
copy_v3_v3(tvec, vec1->vec);
mul_qt_v3(quat2->quat, tvec);
return newVectorObject(tvec, 3, Py_NEW, NULL);
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
int i;
@@ -1587,12 +1594,12 @@ static int Vector_setSwizzle(VectorObject *self, PyObject * value, void *closure
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Vector_getseters[] = {
{"x", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector X axis. **type** float", (void *)0},
{"y", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Y axis. **type** float", (void *)1},
{"z", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Z axis (3D Vectors only). **type** float", (void *)2},
{"w", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector W axis (4D Vectors only). **type** float", (void *)3},
{"length", (getter)Vector_getLength, (setter)Vector_setLength, "Vector Length. **type** float", NULL},
{"magnitude", (getter)Vector_getLength, (setter)Vector_setLength, "Vector Length. **type** float", NULL},
{"x", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector X axis.\n\n:type: float", (void *)0},
{"y", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Y axis.\n\n:type: float", (void *)1},
{"z", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Z axis (3D Vectors only).\n\n:type: float", (void *)2},
{"w", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector W axis (4D Vectors only).\n\n:type: float", (void *)3},
{"length", (getter)Vector_getLength, (setter)Vector_setLength, "Vector Length.\n\n:type: float", NULL},
{"magnitude", (getter)Vector_getLength, (setter)Vector_setLength, "Vector Length.\n\n:type: float", NULL},
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
{"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},

View File

@@ -67,7 +67,7 @@ PyObject *bpy_script_paths(PyObject *self)
static char bpy_blend_paths_doc[] =
".. function:: blend_paths(absolute=False)\n"
"\n"
" Returns a list of paths associated with this blend file.\n"
" Returns a list of paths to external files referenced by the loaded .blend file.\n"
"\n"
" :arg absolute: When true the paths returned are made absolute.\n"
" :type absolute: boolean\n"

View File

@@ -146,28 +146,6 @@ void BPY_update_modules( void )
bpy_context_module->ptr.data= (void *)BPy_GetContext();
}
/*****************************************************************************
* Description: This function creates a new Python dictionary object.
* note: dict is owned by sys.modules["__main__"] module, reference is borrowed
* note: important we use the dict from __main__, this is what python expects
for 'pickle' to work as well as strings like this...
>> foo = 10
>> print(__import__("__main__").foo)
*****************************************************************************/
static PyObject *CreateGlobalDictionary(bContext *C, const char *filename)
{
PyInterpreterState *interp= PyThreadState_GET()->interp;
PyObject *mod_main= PyModule_New("__main__");
PyDict_SetItemString(interp->modules, "__main__", mod_main);
Py_DECREF(mod_main); /* sys.modules owns now */
PyModule_AddObject(mod_main, "__builtins__", interp->builtins);
PyModule_AddStringConstant(mod_main, "__name__", "__main__");
PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */
return PyModule_GetDict(mod_main);
}
/* must be called before Py_Initialize */
void BPY_start_python_path(void)
{
@@ -329,13 +307,13 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
if (fn==NULL && text==NULL) {
return 0;
}
bpy_context_set(C, &gilstate);
if (text) {
char fn_dummy[FILE_MAXDIR];
bpy_text_filename_get(fn_dummy, text);
py_dict = CreateGlobalDictionary(C, fn_dummy);
py_dict = bpy_namespace_dict_new(fn_dummy);
if( !text->compiled ) { /* if it wasn't already compiled, do it now */
char *buf = txt_to_buf( text );
@@ -356,7 +334,7 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
else {
FILE *fp= fopen(fn, "r");
py_dict = CreateGlobalDictionary(C, fn);
py_dict = bpy_namespace_dict_new(fn);
if(fp) {
#ifdef _WIN32
@@ -500,7 +478,7 @@ int BPY_run_python_script_space(const char *modulename, const char *func)
gilstate = PyGILState_Ensure();
py_dict = CreateGlobalDictionary(C);
py_dict = bpy_namespace_dict_new("<dummy>");
PyObject *module = PyImport_ImportModule(scpt->script.filename);
if (module==NULL) {
@@ -552,7 +530,7 @@ int BPY_eval_button(bContext *C, const char *expr, double *value)
bpy_context_set(C, &gilstate);
py_dict= CreateGlobalDictionary(C, "<blender button>");
py_dict= bpy_namespace_dict_new("<blender button>");
mod = PyImport_ImportModule("math");
if (mod) {
@@ -623,7 +601,7 @@ int BPY_eval_string(bContext *C, const char *expr)
bpy_context_set(C, &gilstate);
py_dict= CreateGlobalDictionary(C, "<blender string>");
py_dict= bpy_namespace_dict_new("<blender string>");
retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict);

View File

@@ -4388,7 +4388,7 @@ static int rna_function_arg_count(FunctionRNA *func)
const ListBase *lb= RNA_function_defined_parameters(func);
PropertyRNA *parm;
Link *link;
int count= 1;
int count= (RNA_function_flag(func) & FUNC_NO_SELF) ? 0 : 1;
for(link=lb->first; link; link=link->next) {
parm= (PropertyRNA*)link;
@@ -4409,7 +4409,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
const char *class_type= RNA_struct_identifier(srna);
PyObject *py_class= (PyObject*)py_data;
PyObject *base_class= RNA_struct_py_type_get(srna);
PyObject *item, *fitem;
PyObject *item;
PyObject *py_arg_count;
int i, flag, arg_count, func_arg_count;
const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; // __name__
@@ -4446,25 +4446,33 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
PyErr_Clear();
}
else {
Py_DECREF(item); /* no need to keep a ref, the class owns it */
if (PyMethod_Check(item))
fitem= PyMethod_Function(item); /* py 2.x */
else
fitem= item; /* py 3.x */
if (PyFunction_Check(fitem)==0) {
PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a function", class_type, py_class_name, RNA_function_identifier(func));
return -1;
Py_DECREF(item); /* no need to keep a ref, the class owns it (technically we should keep a ref but...) */
if(flag & FUNC_NO_SELF) {
if (PyMethod_Check(item)==0) {
PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a method, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name);
return -1;
}
item= ((PyMethodObject *)item)->im_func;
}
else {
if (PyFunction_Check(item)==0) {
PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a function, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name);
return -1;
}
}
func_arg_count= rna_function_arg_count(func);
if (func_arg_count >= 0) { /* -1 if we dont care*/
py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(fitem), "co_argcount");
py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(item), "co_argcount");
arg_count = PyLong_AsSsize_t(py_arg_count);
Py_DECREF(py_arg_count);
/* note, the number of args we check for and the number of args we give to
* @classmethods are different (quirk of python), this is why rna_function_arg_count() doesn't return the value -1*/
if(flag & FUNC_NO_SELF)
func_arg_count++;
if (arg_count != func_arg_count) {
PyErr_Format( PyExc_AttributeError, "expected %.200s, %.200s class \"%.200s\" function to have %d args, found %d", class_type, py_class_name, RNA_function_identifier(func), func_arg_count, arg_count);
return -1;
@@ -4537,6 +4545,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
ParameterIterator iter;
PointerRNA funcptr;
int err= 0, i, flag, ret_len=0;
int is_static = RNA_function_flag(func) & FUNC_NO_SELF;
PropertyRNA *pret_single= NULL;
void *retdata_single= NULL;
@@ -4544,55 +4553,64 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
PyGILState_STATE gilstate;
bContext *C= BPy_GetContext(); // XXX - NEEDS FIXING, QUITE BAD.
bpy_context_set(C, &gilstate);
py_class= RNA_struct_py_type_get(ptr->type);
/* exception, operators store their PyObjects for re-use */
if(ptr->data) {
if(RNA_struct_is_a(ptr->type, &RNA_Operator)) {
wmOperator *op= ptr->data;
if(op->py_instance) {
py_class_instance= op->py_instance;
/* rare case. can happen when registering subclasses */
if(py_class==NULL) {
fprintf(stderr, "bpy_class_call(): unable to get python class for rna struct '%.200s'\n", RNA_struct_identifier(ptr->type));
return -1;
}
bpy_context_set(C, &gilstate);
if (!is_static) {
/* exception, operators store their PyObjects for re-use */
if(ptr->data) {
if(RNA_struct_is_a(ptr->type, &RNA_Operator)) {
wmOperator *op= ptr->data;
if(op->py_instance) {
py_class_instance= op->py_instance;
Py_INCREF(py_class_instance);
}
else {
/* store the instance here once its created */
py_class_instance_store= &op->py_instance;
}
}
}
/* end exception */
if(py_class_instance==NULL)
py_srna= pyrna_struct_CreatePyObject(ptr);
if(py_class_instance) {
/* special case, instance is cached */
}
else if(py_srna == NULL) {
py_class_instance = NULL;
}
else if(py_srna == Py_None) { /* probably wont ever happen but possible */
Py_DECREF(py_srna);
py_class_instance = NULL;
}
else {
args = PyTuple_New(1);
PyTuple_SET_ITEM(args, 0, py_srna);
py_class_instance= PyObject_Call(py_class, args, NULL);
Py_DECREF(args);
if(py_class_instance == NULL) {
err= -1; /* so the error is not overridden below */
}
else if(py_class_instance_store) {
*py_class_instance_store = py_class_instance;
Py_INCREF(py_class_instance);
}
else {
/* store the instance here once its created */
py_class_instance_store= &op->py_instance;
}
}
}
/* end exception */
if(py_class_instance==NULL)
py_srna= pyrna_struct_CreatePyObject(ptr);
if(py_class_instance) {
/* special case, instance is cached */
}
else if(py_srna == NULL) {
py_class_instance = NULL;
}
else if(py_srna == Py_None) { /* probably wont ever happen but possible */
Py_DECREF(py_srna);
py_class_instance = NULL;
}
else {
args = PyTuple_New(1);
PyTuple_SET_ITEM(args, 0, py_srna);
py_class_instance= PyObject_Call(py_class, args, NULL);
Py_DECREF(args);
if(py_class_instance == NULL) {
err= -1; /* so the error is not overridden below */
}
else if(py_class_instance_store) {
*py_class_instance_store = py_class_instance;
Py_INCREF(py_class_instance);
}
}
if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
if (is_static || py_class_instance) { /* Initializing the class worked, now run its invoke function */
PyObject *item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
// flag= RNA_function_flag(func);
@@ -4600,12 +4618,19 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */
PyTuple_SET_ITEM(args, 0, py_class_instance);
if(is_static) {
i= 0;
}
else {
PyTuple_SET_ITEM(args, 0, py_class_instance);
i= 1;
}
RNA_parameter_list_begin(parms, &iter);
/* parse function parameters */
for (i= 1; iter.valid; RNA_parameter_list_next(&iter)) {
for (; iter.valid; RNA_parameter_list_next(&iter)) {
parm= iter.parm;
flag= RNA_property_flag(parm);
@@ -4736,7 +4761,16 @@ void pyrna_alloc_types(void)
prop = RNA_struct_find_property(&ptr, "structs");
RNA_PROP_BEGIN(&ptr, itemptr, prop) {
Py_DECREF(pyrna_struct_Subtype(&itemptr));
PyObject *item= pyrna_struct_Subtype(&itemptr);
if(item == NULL) {
if(PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
}
}
else {
Py_DECREF(item);
}
}
RNA_PROP_END;
@@ -4799,6 +4833,14 @@ static PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class)
if(srna==NULL)
return NULL;
/* fails in cases, cant use this check but would like to :| */
/*
if(RNA_struct_py_type_get(srna)) {
PyErr_Format(PyExc_ValueError, "bpy.types.register(...): %.200s's parent class %.200s is alredy registered, this is not allowed.", ((PyTypeObject*)py_class)->tp_name, RNA_struct_identifier(srna));
return NULL;
}
*/
/* check that we have a register callback for this type */
reg= RNA_struct_register(srna);

View File

@@ -64,19 +64,28 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
char *cb_event_str= NULL;
int cb_event;
if (!PyArg_ParseTuple(args, "OO|s:bpy_struct.callback_add", &cb_func, &cb_args, &cb_event_str))
if (!PyArg_ParseTuple(args, "OO!|s:bpy_struct.callback_add", &cb_func, &PyTuple_Type, &cb_args, &cb_event_str))
return NULL;
if(!PyCallable_Check(cb_func)) {
PyErr_SetString(PyExc_TypeError, "callback_add(): first argument isn't callable");
return NULL;
}
if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
static EnumPropertyItem region_draw_mode_items[] = {
{REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Pose View", ""},
{REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
{REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
{0, NULL, 0, NULL, NULL}};
if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0)
return NULL;
if(cb_event_str) {
static EnumPropertyItem region_draw_mode_items[] = {
{REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
{REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
{REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
{0, NULL, 0, NULL, NULL}};
if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0)
return NULL;
}
else {
cb_event= REGION_DRAW_POST_PIXEL;
}
handle= ED_region_draw_cb_activate(((ARegion *)self->ptr.data)->type, cb_region_draw, (void *)args, cb_event);
Py_INCREF(args);