Merged changes in the trunk up to revision 31630.

This commit is contained in:
2010-08-28 14:30:52 +00:00
259 changed files with 2948 additions and 1773 deletions

View File

@@ -22,4 +22,4 @@ env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Spli
# generic
sources = env.Glob('generic/*.c')
env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # ketsji is 360
env.BlenderLib( libname = 'bf_python_ext', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # ketsji is 360

View File

@@ -31,4 +31,4 @@ SET(INC
${PYTHON_INC}
)
BLENDERLIB(bf_gen_python "${SRC}" "${INC}")
BLENDERLIB(bf_python_ext "${SRC}" "${INC}")

View File

@@ -1526,7 +1526,6 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
return NULL;
}
else /* if(mat1) { */ {
if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */
return column_vector_multiplication(mat1, (VectorObject *)m2); /* vector update done inside the function */
}

View File

@@ -39,7 +39,7 @@
#define SWIZZLE_VALID_AXIS 0x4
#define SWIZZLE_AXIS 0x3
static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); /* utility func */
static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObject * mat); /* utility func */
static PyObject *Vector_ToTupleExt(VectorObject *self, int ndigits);
//----------------------------------mathutils.Vector() ------------------
@@ -1002,7 +1002,11 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
return PyFloat_FromDouble(dot);
}
/*swap so vec1 is always the vector */
/* swap so vec1 is always the vector */
/* note: it would seem from this code that the matrix multiplication below
* is communicative. however the matrix class will always handle the
* (matrix * vector) case so we can ignore it here.
* This is NOT so for Quaternions: TODO, check if communicative (vec * quat) is correct */
if (vec2) {
vec1= vec2;
v2= v1;
@@ -1010,7 +1014,10 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
if (MatrixObject_Check(v2)) {
/* VEC * MATRIX */
return row_vector_multiplication(vec1, (MatrixObject*)v2);
float tvec[4];
if(row_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1)
return NULL;
return newVectorObject(tvec, vec1->size, Py_NEW, NULL);
} else if (QuaternionObject_Check(v2)) {
/* VEC * QUAT */
QuaternionObject *quat2 = (QuaternionObject*)v2;
@@ -1056,42 +1063,20 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
/* only support vec*=float and vec*=mat
vec*=vec result is a float so that wont work */
if (MatrixObject_Check(v2)) {
float vecCopy[4];
int x,y, size = vec->size;
MatrixObject *mat= (MatrixObject*)v2;
if(!BaseMath_ReadCallback(mat))
float tvec[4];
if(row_vector_multiplication(tvec, vec, (MatrixObject*)v2) == -1)
return NULL;
if(mat->colSize != size){
if(mat->rowSize == 4 && vec->size != 3){
PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same");
return NULL;
} else {
vecCopy[3] = 1.0f;
}
}
for(i = 0; i < size; i++){
vecCopy[i] = vec->vec[i];
}
size = MIN2(size, mat->colSize);
/*muliplication*/
for(x = 0, i = 0; x < size; x++, i++) {
double dot = 0.0f;
for(y = 0; y < mat->rowSize; y++) {
dot += mat->matrix[y][x] * vecCopy[y];
}
vec->vec[i] = (float)dot;
}
i= vec->size - 1;
do {
vec->vec[i] = tvec[i];
} while(i--);
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */
for(i = 0; i < vec->size; i++) {
i= vec->size - 1;
do {
vec->vec[i] *= scalar;
}
} while(i--);
}
else {
PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n");
@@ -1992,37 +1977,37 @@ if len(unique) != len(items):
// [2][5][8]
// [3][6][9]
//vector/matrix multiplication IS NOT COMMUTATIVE!!!!
static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat)
static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObject * mat)
{
float vecNew[4], vecCopy[4];
float vecCopy[4];
double dot = 0.0f;
int x, y, z = 0, vec_size = vec->size;
if(mat->colSize != vec_size){
if(mat->colSize == 4 && vec_size != 3){
PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same");
return NULL;
return -1;
}else{
vecCopy[3] = 1.0f;
}
}
if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat))
return NULL;
return -1;
for(x = 0; x < vec_size; x++){
vecCopy[x] = vec->vec[x];
}
vecNew[3] = 1.0f;
rvec[3] = 1.0f;
//muliplication
for(x = 0; x < mat->rowSize; x++) {
for(y = 0; y < mat->colSize; y++) {
dot += mat->matrix[x][y] * vecCopy[y];
}
vecNew[z++] = (float)dot;
rvec[z++] = (float)dot;
dot = 0.0f;
}
return newVectorObject(vecNew, vec_size, Py_NEW, NULL);
return 0;
}
/*----------------------------Vector.negate() -------------------- */

View File

@@ -49,6 +49,7 @@
#include "ED_keyframing.h"
#define USE_MATHUTILS
#define USE_STRING_COERCE
#ifdef USE_MATHUTILS
#include "../generic/mathutils.h" /* so we can have mathutils callbacks */
@@ -192,6 +193,62 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
NULL
};
#ifdef USE_STRING_COERCE
/* string conversion, escape non-unicode chars, coerce must be set to NULL */
static const char *py_safe_unicode_to_byte(PyObject *py_str, PyObject **coerce)
{
char *result;
result= _PyUnicode_AsString(py_str);
if(result) {
/* 99% of the time this is enough but we better support non unicode
* chars since blender doesnt limit this */
return result;
}
else {
/* mostly copied from fileio.c's, fileio_init */
PyObject *stringobj;
PyObject *u;
PyErr_Clear();
u= PyUnicode_FromObject(py_str); /* coerce into unicode */
if (u == NULL)
return NULL;
stringobj= PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(u), PyUnicode_GET_SIZE(u), "surrogateescape");
Py_DECREF(u);
if (stringobj == NULL)
return NULL;
if (!PyBytes_Check(stringobj)) { /* this seems wrong but it works fine */
// printf("encoder failed to return bytes\n");
Py_DECREF(stringobj);
return NULL;
}
*coerce= stringobj;
return PyBytes_AS_STRING(stringobj);
}
}
static PyObject *py_safe_byte_to_unicode(char *str)
{
PyObject *result= PyUnicode_FromString(str);
if(result) {
/* 99% of the time this is enough but we better support non unicode
* chars since blender doesnt limit this */
return result;
}
else {
PyErr_Clear();
result= PyUnicode_DecodeUTF8(str, strlen(str), "surrogateescape");
return result;
}
}
#endif
/* same as RNA_enum_value_from_id but raises an exception */
int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
{
@@ -768,9 +825,20 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
break;
case PROP_STRING:
{
int subtype= RNA_property_subtype(prop);
char *buf;
buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
ret = PyUnicode_FromString( buf );
#ifdef USE_STRING_COERCE
/* only file paths get special treatment, they may contain non utf-8 chars */
if(ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
ret= py_safe_byte_to_unicode(buf);
}
else {
ret= PyUnicode_FromString(buf);
}
#else
ret= PyUnicode_FromString(buf);
#endif
MEM_freeN(buf);
break;
}
@@ -971,16 +1039,31 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, v
}
case PROP_STRING:
{
char *param = _PyUnicode_AsString(value);
const char *param;
#ifdef USE_STRING_COERCE
PyObject *value_coerce= NULL;
int subtype= RNA_property_subtype(prop);
if(ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
param= py_safe_unicode_to_byte(value, &value_coerce);
}
else {
param= _PyUnicode_AsString(value);
}
#else
param= _PyUnicode_AsString(value);
#endif
if (param==NULL) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a string type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop));
return -1;
}
else {
if(data) *((char**)data)= param;
if(data) *((char**)data)= param; /*XXX, this assignes a pointer, wouldnt it be better to copy??? */
else RNA_property_string_set(ptr, prop, param);
}
#ifdef USE_STRING_COERCE
Py_XDECREF(value_coerce);
#endif
break;
}
case PROP_ENUM:
@@ -1016,6 +1099,8 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, v
}
case PROP_POINTER:
{
PyObject *value_new= NULL;
StructRNA *ptype= RNA_property_pointer_type(ptr, prop);
int flag = RNA_property_flag(prop);
@@ -1025,15 +1110,29 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, v
return pyrna_pydict_to_props(&opptr, value, 0, error_prefix);
}
/* another exception, allow to pass a collection as an RNA property */
if(Py_TYPE(value)==&pyrna_prop_collection_Type) {
PointerRNA c_ptr;
BPy_PropertyRNA *value_prop= (BPy_PropertyRNA *)value;
if(RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) {
value= pyrna_struct_CreatePyObject(&c_ptr);
value_new= value;
}
else {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s collection has no type, cant be used as a %.200s type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), RNA_struct_identifier(ptype));
return -1;
}
}
if(!BPy_StructRNA_Check(value) && value != Py_None) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), RNA_struct_identifier(ptype));
return -1;
Py_XDECREF(value_new); return -1;
} else if((flag & PROP_NEVER_NULL) && value == Py_None) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s does not support a 'None' assignment %.200s type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), RNA_struct_identifier(ptype));
return -1;
Py_XDECREF(value_new); return -1;
} else if(value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) {
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s ID type does not support assignment to its self", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop));
return -1;
Py_XDECREF(value_new); return -1;
} else {
BPy_StructRNA *param= (BPy_StructRNA*)value;
int raise_error= FALSE;
@@ -1069,7 +1168,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, v
PointerRNA tmp;
RNA_pointer_create(NULL, ptype, NULL, &tmp);
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), RNA_struct_identifier(tmp.type));
return -1;
Py_XDECREF(value_new); return -1;
}
}
@@ -1077,9 +1176,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, v
PointerRNA tmp;
RNA_pointer_create(NULL, ptype, NULL, &tmp);
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), RNA_struct_identifier(tmp.type));
return -1;
Py_XDECREF(value_new); return -1;
}
}
break;
}
case PROP_COLLECTION:
@@ -1238,6 +1338,25 @@ static Py_ssize_t pyrna_prop_collection_length( BPy_PropertyRNA *self )
return RNA_property_collection_length(&self->ptr, self->prop);
}
/* bool funcs are for speed, so we can avoid getting the length
* of 1000's of items in a linked list for eg. */
static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
{
return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
}
static int pyrna_prop_collection_bool( BPy_PropertyRNA *self )
{
/* no callback defined, just iterate and find the nth item */
CollectionPropertyIterator iter;
int test;
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
test = iter.valid;
RNA_property_collection_end(&iter);
return test;
}
/* internal use only */
static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum)
{
@@ -1250,10 +1369,11 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d could not be found", keynum);
return NULL;
else { /* fail's if ptr.data == NULL, valid for mesh.materials */
Py_RETURN_NONE;
}
}
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range", keynum);
PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range, size %d", keynum, len);
return NULL;
}
@@ -1270,7 +1390,7 @@ static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyRNA *self, int keynu
return NULL;
}
static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, char *keyname)
static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
{
PointerRNA newptr;
if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
@@ -1629,6 +1749,31 @@ static PyMappingMethods pyrna_prop_collection_as_mapping = {
( objobjargproc ) NULL, /* mp_ass_subscript */
};
/* only for fast bool's, large structs, assign nb_bool on init */
static PyNumberMethods pyrna_prop_array_as_number = {
NULL, /* nb_add */
NULL, /* nb_subtract */
NULL, /* nb_multiply */
NULL, /* nb_remainder */
NULL, /* nb_divmod */
NULL, /* nb_power */
NULL, /* nb_negative */
NULL, /* nb_positive */
NULL, /* nb_absolute */
(inquiry) pyrna_prop_array_bool, /* nb_bool */
};
static PyNumberMethods pyrna_prop_collection_as_number = {
NULL, /* nb_add */
NULL, /* nb_subtract */
NULL, /* nb_multiply */
NULL, /* nb_remainder */
NULL, /* nb_divmod */
NULL, /* nb_power */
NULL, /* nb_negative */
NULL, /* nb_positive */
NULL, /* nb_absolute */
(inquiry) pyrna_prop_collection_bool, /* nb_bool */
};
static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value)
{
@@ -2141,25 +2286,37 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *
}
static char pyrna_struct_path_resolve_doc[] =
".. method:: path_resolve(path)\n"
".. method:: path_resolve(path, coerce=True)\n"
"\n"
" Returns the property from the path given or None if the property is not found.";
" Returns the property from the path, raise an exception when not found.\n"
"\n"
" :arg path: path which this property resolves.\n"
" :type path: string\n"
" :arg coerce: optional argument, when True, the property will be converted into its python representation.\n"
" :type coerce: boolean\n";
static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *value)
static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
{
char *path= _PyUnicode_AsString(value);
char *path;
PyObject *coerce= Py_True;
PointerRNA r_ptr;
PropertyRNA *r_prop;
if(path==NULL) {
PyErr_SetString(PyExc_TypeError, "bpy_struct.path_resolve(): accepts only a single string argument");
if (!PyArg_ParseTuple(args, "s|O!:path_resolve", &path, &PyBool_Type, &coerce))
return NULL;
if (RNA_path_resolve(&self->ptr, path, &r_ptr, &r_prop)) {
if(coerce == Py_False) {
return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
}
else {
return pyrna_prop_to_py(&r_ptr, r_prop);
}
}
else {
PyErr_Format(PyExc_TypeError, "%.200s.path_resolve(\"%.200s\") could not be resolved", RNA_struct_identifier(self->ptr.type), path);
return NULL;
}
if (RNA_path_resolve(&self->ptr, path, &r_ptr, &r_prop))
return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
Py_RETURN_NONE;
}
static char pyrna_struct_path_from_id_doc[] =
@@ -2234,15 +2391,15 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
return ret;
}
static char pyrna_struct_recast_type_doc[] =
".. method:: recast_type()\n"
static char pyrna_struct_type_recast_doc[] =
".. method:: type_recast()\n"
"\n"
" Return a new instance, this is needed because types such as textures can be changed at runtime.\n"
"\n"
" :return: a new instance of this object with the type initialized again.\n"
" :rtype: subclass of :class:`bpy_struct`";
static PyObject *pyrna_struct_recast_type(BPy_StructRNA *self, PyObject *args)
static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self, PyObject *args)
{
PointerRNA r_ptr;
RNA_pointer_recast(&self->ptr, &r_ptr);
@@ -2496,10 +2653,16 @@ static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObjec
}
/* pyrna_py_to_prop sets its own exceptions */
if(prop)
if(prop) {
if(value == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported");
return -1;
}
return pyrna_py_to_prop(&self->ptr, prop, NULL, NULL, value, "bpy_struct: item.attr = val:");
else
}
else {
return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
}
}
static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
@@ -2564,6 +2727,11 @@ static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyna
PropertyRNA *prop;
PointerRNA r_ptr;
if(value == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported");
return -1;
}
if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if ((prop = RNA_struct_find_property(&r_ptr, name))) {
/* pyrna_py_to_prop sets its own exceptions */
@@ -2632,8 +2800,9 @@ static PyObject *pyrna_prop_move(BPy_PropertyRNA *self, PyObject *args)
return ret;
}
static PyObject *pyrna_struct_get_id_data(BPy_StructRNA *self)
static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self)
{
/* used for struct and pointer since both have a ptr */
if(self->ptr.id.data) {
PointerRNA id_ptr;
RNA_id_pointer_create((ID *)self->ptr.id.data, &id_ptr);
@@ -2646,12 +2815,12 @@ static PyObject *pyrna_struct_get_id_data(BPy_StructRNA *self)
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
#if 0
static PyGetSetDef pyrna_prop_getseters[] = {
{"active", (getter)pyrna_prop_get_active, (setter)pyrna_prop_set_active, "", NULL},
{"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, "The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
#endif
static PyGetSetDef pyrna_struct_getseters[] = {
{"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, "The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL},
@@ -3111,15 +3280,29 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"driver_remove", (PyCFunction)pyrna_struct_driver_remove, METH_VARARGS, pyrna_struct_driver_remove_doc},
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, pyrna_struct_is_property_set_doc},
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, pyrna_struct_is_property_hidden_doc},
{"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_O, pyrna_struct_path_resolve_doc},
{"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_VARARGS, pyrna_struct_path_resolve_doc},
{"path_from_id", (PyCFunction)pyrna_struct_path_from_id, METH_VARARGS, pyrna_struct_path_from_id_doc},
{"recast_type", (PyCFunction)pyrna_struct_recast_type, METH_NOARGS, pyrna_struct_recast_type_doc},
{"type_recast", (PyCFunction)pyrna_struct_type_recast, METH_NOARGS, pyrna_struct_type_recast_doc},
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
/* experemental */
{"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL},
{"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL},
/* class methods, only valid for subclasses */
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_BoolProperty_doc},
{"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_BoolVectorProperty_doc},
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_IntProperty_doc},
{"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_IntVectorProperty_doc},
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_FloatProperty_doc},
{"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_FloatVectorProperty_doc},
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_StringProperty_doc},
{"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_EnumProperty_doc},
{"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_PointerProperty_doc},
{"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_CollectionProperty_doc},
{"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_RemoveProperty_doc},
{NULL, NULL, 0, NULL}
};
@@ -3272,10 +3455,30 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, ParameterList *parms, PropertyRNA *
break;
case PROP_STRING:
{
if(flag & PROP_THICK_WRAP)
ret = PyUnicode_FromString( (char*)data );
char *data_ch;
PyObject *value_coerce= NULL;
int subtype= RNA_property_subtype(prop);
if (flag & PROP_THICK_WRAP)
data_ch= (char *)data;
else
ret = PyUnicode_FromString( *(char**)data );
data_ch= *(char **)data;
#ifdef USE_STRING_COERCE
if(ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
ret= py_safe_byte_to_unicode(data_ch);
}
else {
ret= PyUnicode_FromString(data_ch);
}
#else
ret = PyUnicode_FromString(data_ch);
#endif
#ifdef USE_STRING_COERCE
Py_XDECREF(value_coerce);
#endif
break;
}
case PROP_ENUM:
@@ -3712,7 +3915,7 @@ PyTypeObject pyrna_prop_Type = {
/*** Attribute descriptor and subclassing stuff ***/
pyrna_prop_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
NULL /*pyrna_prop_getseters*/, /* struct PyGetSetDef *tp_getset; */
pyrna_prop_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
@@ -3749,7 +3952,7 @@ PyTypeObject pyrna_prop_array_Type = {
/* Method suites for standard classes */
NULL, /* PyNumberMethods *tp_as_number; */
&pyrna_prop_array_as_number, /* PyNumberMethods *tp_as_number; */
&pyrna_prop_array_as_sequence, /* PySequenceMethods *tp_as_sequence; */
&pyrna_prop_array_as_mapping, /* PyMappingMethods *tp_as_mapping; */
@@ -3829,7 +4032,7 @@ PyTypeObject pyrna_prop_collection_Type = {
/* Method suites for standard classes */
NULL, /* PyNumberMethods *tp_as_number; */
&pyrna_prop_collection_as_number, /* PyNumberMethods *tp_as_number; */
&pyrna_prop_collection_as_sequence, /* PySequenceMethods *tp_as_sequence; */
&pyrna_prop_collection_as_mapping, /* PyMappingMethods *tp_as_mapping; */
@@ -3894,28 +4097,11 @@ PyTypeObject pyrna_prop_collection_Type = {
NULL
};
static struct PyMethodDef pyrna_struct_subtype_methods[] = {
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc},
{"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolVectorProperty_doc},
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntProperty_doc},
{"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntVectorProperty_doc},
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatProperty_doc},
{"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatVectorProperty_doc},
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, BPy_StringProperty_doc},
{"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, BPy_EnumProperty_doc},
{"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, BPy_PointerProperty_doc},
{"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, BPy_CollectionProperty_doc},
{"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, BPy_RemoveProperty_doc},
// {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""},
{NULL, NULL, 0, NULL}
};
static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
{
PointerRNA ptr;
PyObject *item;
PyObject *newclass_dict= ((PyTypeObject *)newclass)->tp_dict;
Py_INCREF(newclass);
@@ -3934,20 +4120,9 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
item = pyrna_struct_CreatePyObject(&ptr);
//item = PyCapsule_New(srna, NULL, NULL);
PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "bl_rna", item);
PyDict_SetItemString(newclass_dict, "bl_rna", item);
Py_DECREF(item);
/* done with rna instance */
/* attach functions into the class
* so you can do... bpy.types.Scene.SomeFunction()
*/
{
PyMethodDef *ml;
for(ml= pyrna_struct_subtype_methods; ml->ml_name; ml++){
PyObject_SetAttrString(newclass, ml->ml_name, PyCFunction_New(ml, newclass));
}
}
}
static PyObject* pyrna_srna_Subtype(StructRNA *srna);
@@ -4034,14 +4209,19 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
{
PyObject *newclass = NULL;
/* stupid/simple case */
if (srna == NULL) {
newclass= NULL; /* Nothing to do */
} else if ((newclass= RNA_struct_py_type_get(srna))) {
} /* the class may have alredy been declared & allocated */
else if ((newclass= RNA_struct_py_type_get(srna))) {
Py_INCREF(newclass);
} else if ((newclass= pyrna_srna_ExternalType(srna))) {
} /* check if bpy_types.py module has the class defined in it */
else if ((newclass= pyrna_srna_ExternalType(srna))) {
pyrna_subtype_set_rna(newclass, srna);
Py_INCREF(newclass);
} else {
} /* create a new class instance with the C api
* maintly for the purposing of matching the C/rna type hierarchy */
else {
/* subclass equivelents
- class myClass(myBase):
some='value' # or ...
@@ -4052,12 +4232,14 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
PyObject *py_base= pyrna_srna_PyBase(srna);
const char *idname= RNA_struct_identifier(srna);
const char *descr= RNA_struct_ui_description(srna);
if(!descr) descr= "(no docs)";
/* remove __doc__ for now */
// const char *descr= RNA_struct_ui_description(srna);
// if(!descr) descr= "(no docs)";
// "__doc__",descr
/* always use O not N when calling, N causes refcount errors */
newclass = PyObject_CallFunction( (PyObject*)&PyType_Type, "s(O){sssss()}", idname, py_base, "__module__","bpy.types", "__doc__",descr, "__slots__");
newclass = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sss()}", idname, py_base, "__module__","bpy.types", "__slots__");
/* newclass will now have 2 ref's, ???, probably 1 is internal since decrefing here segfaults */
/* PyObSpit("new class ref", newclass); */
@@ -4066,7 +4248,8 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna)
/* srna owns one, and the other is owned by the caller */
pyrna_subtype_set_rna(newclass, srna);
Py_DECREF(newclass); /* let srna own */
// XXX, adding this back segfaults blender on load.
// Py_DECREF(newclass); /* let srna own */
}
else {
/* this should not happen */
@@ -4667,7 +4850,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
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) {