NLA SoC: Merge from 2.5 - 21146 to 21178

This commit is contained in:
2009-06-27 03:19:55 +00:00
59 changed files with 1749 additions and 1323 deletions

View File

@@ -164,6 +164,10 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq )
for( index = 0; index<len_polypoints; ++index, fp+=3) {
polyVec= PySequence_GetItem( polyLine, index );
if(VectorObject_Check(polyVec)) {
if(!BaseMath_ReadCallback((VectorObject *)polyVec))
ls_error= 1;
fp[0] = ((VectorObject *)polyVec)->vec[0];
fp[1] = ((VectorObject *)polyVec)->vec[1];
if( ((VectorObject *)polyVec)->size > 2 )
@@ -234,6 +238,9 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args )
return NULL;
}
if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2))
return NULL;
a1x= line_a1->vec[0];
a1y= line_a1->vec[1];
a2x= line_a2->vec[0];
@@ -330,6 +337,10 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args
PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" );
return NULL;
}
if(!BaseMath_ReadCallback(pt) || !BaseMath_ReadCallback(line_1) || !BaseMath_ReadCallback(line_2))
return NULL;
/* accept 2d verts */
if (pt->size==3) { VECCOPY(pt_in, pt->vec);}
else { pt_in[2]=0.0; VECCOPY2D(pt_in, pt->vec) }
@@ -363,6 +374,9 @@ static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args
return NULL;
}
if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(tri_p1) || !BaseMath_ReadCallback(tri_p2) || !BaseMath_ReadCallback(tri_p3))
return NULL;
return PyLong_FromLong(IsectPT2Df(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec));
}
@@ -381,6 +395,9 @@ static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args )
return NULL;
}
if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(quad_p1) || !BaseMath_ReadCallback(quad_p2) || !BaseMath_ReadCallback(quad_p3) || !BaseMath_ReadCallback(quad_p4))
return NULL;
return PyLong_FromLong(IsectPQ2Df(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec));
}
@@ -500,6 +517,9 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args )
return NULL;
}
if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2))
return NULL;
dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i];

View File

@@ -155,10 +155,13 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
if(QuaternionObject_Check(arg1)){
quat = (QuaternionObject*)arg1;
if(!BaseMath_ReadCallback(quat))
return NULL;
if(VectorObject_Check(arg2)){
vec = (VectorObject*)arg2;
if(!Vector_ReadCallback(vec))
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] -
@@ -178,11 +181,14 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
}else if(VectorObject_Check(arg1)){
vec = (VectorObject*)arg1;
if(!Vector_ReadCallback(vec))
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] -
@@ -247,7 +253,7 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
if(vec1->size != vec2->size)
goto AttributeError1; //bad sizes
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
//since size is the same....
@@ -269,8 +275,11 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
angleRads = (double)saacos(dot);
#ifdef USE_MATHUTILS_DEG
return PyFloat_FromDouble(angleRads * (180/ Py_PI));
#else
return PyFloat_FromDouble(angleRads);
#endif
AttributeError1:
PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): expects (2) VECTOR objects of the same size\n");
return NULL;
@@ -296,7 +305,7 @@ static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
return NULL;
}
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
for(x = 0; x < vec1->size; x++) {
@@ -322,7 +331,7 @@ static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
return NULL;
}
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
@@ -358,12 +367,19 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): expected float int and optional string and vector\n");
return NULL;
}
#ifdef USE_MATHUTILS_DEG
/* Clamp to -360:360 */
while (angle<-360.0f)
angle+=360.0;
while (angle>360.0f)
angle-=360.0;
#else
while (angle<-(Py_PI*2))
angle+=(Py_PI*2);
while (angle>(Py_PI*2))
angle-=(Py_PI*2);
#endif
if(matSize != 2 && matSize != 3 && matSize != 4) {
PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
@@ -389,12 +405,15 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
return NULL;
}
if(!Vector_ReadCallback(vec))
if(!BaseMath_ReadCallback(vec))
return NULL;
}
#ifdef USE_MATHUTILS_DEG
//convert to radians
angle = angle * (float) (Py_PI / 180);
#endif
if(axis == NULL && matSize == 2) {
//2D rotation matrix
mat[0] = (float) cos (angle);
@@ -492,7 +511,7 @@ static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * v
return NULL;
}
if(!Vector_ReadCallback(vec))
if(!BaseMath_ReadCallback(vec))
return NULL;
//create a identity matrix and add translation
@@ -528,7 +547,7 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
return NULL;
}
if(!Vector_ReadCallback(vec))
if(!BaseMath_ReadCallback(vec))
return NULL;
}
@@ -607,7 +626,7 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
return NULL;
}
if(!Vector_ReadCallback(vec))
if(!BaseMath_ReadCallback(vec))
return NULL;
}
@@ -766,6 +785,10 @@ static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
PyErr_SetString(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types");
return NULL;
}
if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
return NULL;
tempQuat[0] = quatU->quat[0];
tempQuat[1] = -quatU->quat[1];
tempQuat[2] = -quatU->quat[2];
@@ -793,6 +816,10 @@ static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float");
return NULL;
}
if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
return NULL;
if(param > 1.0f || param < 0.0f) {
PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0");
return NULL;
@@ -856,7 +883,7 @@ static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
return NULL;
}
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(ray) || !Vector_ReadCallback(ray_off))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off))
return NULL;
VECCOPY(v1, vec1->vec);
@@ -928,7 +955,7 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
return NULL;
}
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(vec4))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
return NULL;
if( vec1->size == 3 || vec1->size == 2) {
@@ -1002,7 +1029,7 @@ static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
return NULL;
}
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(vec4))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
return NULL;
VECCOPY(v1, vec1->vec);
@@ -1050,7 +1077,7 @@ static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
return NULL;
}
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
return NULL;
VECCOPY(v1, vec1->vec);
@@ -1085,7 +1112,7 @@ static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
return NULL;
}
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
return NULL;
if (vec1->size == 3) {
@@ -1167,75 +1194,66 @@ int Mathutils_RegisterCallback(Mathutils_Callback *cb)
}
/* use macros to check for NULL */
int _Vector_ReadCallback(VectorObject *self)
int _BaseMathObject_ReadCallback(BaseMathObject *self)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->get(self->cb_user, self->cb_subtype, self->vec)) {
if(cb->get(self->cb_user, self->cb_subtype, self->data))
return 1;
}
else {
PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
return 0;
}
PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
return 0;
}
int _Vector_WriteCallback(VectorObject *self)
int _BaseMathObject_WriteCallback(BaseMathObject *self)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->set(self->cb_user, self->cb_subtype, self->vec)) {
if(cb->set(self->cb_user, self->cb_subtype, self->data))
return 1;
}
else {
PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
return 0;
}
PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
return 0;
}
int _Vector_ReadIndexCallback(VectorObject *self, int index)
int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->get_index(self->cb_user, self->cb_subtype, self->vec, index)) {
if(cb->get_index(self->cb_user, self->cb_subtype, self->data, index))
return 1;
}
else {
PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
return 0;
}
PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
return 0;
}
int _Vector_WriteIndexCallback(VectorObject *self, int index)
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->set_index(self->cb_user, self->cb_subtype, self->vec, index)) {
if(cb->set_index(self->cb_user, self->cb_subtype, self->data, index))
return 1;
}
else {
PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
return 0;
}
PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
return 0;
}
/* matrix callbacks */
int _Matrix_ReadCallback(MatrixObject *self)
/* BaseMathObject generic functions for all mathutils types */
PyObject *BaseMathObject_getOwner( BaseMathObject * self, void *type )
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->get(self->cb_user, self->cb_subtype, self->contigPtr)) {
return 1;
}
else {
PyErr_SetString(PyExc_SystemError, "Matrix user has become invalid");
return 0;
}
PyObject *ret= self->cb_user ? self->cb_user : Py_None;
Py_INCREF(ret);
return ret;
}
int _Matrix_WriteCallback(MatrixObject *self)
PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void *type )
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
if(cb->set(self->cb_user, self->cb_subtype, self->contigPtr)) {
return 1;
}
else {
PyErr_SetString(PyExc_SystemError, "Matrix user has become invalid");
return 0;
}
PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0);
}
void BaseMathObject_dealloc(BaseMathObject * self)
{
/* only free non wrapped */
if(self->wrapped != Py_WRAP)
PyMem_Free(self->data);
Py_XDECREF(self->cb_user);
PyObject_DEL(self);
}

View File

@@ -38,6 +38,26 @@
#include "quat.h"
#include "euler.h"
/* #define USE_MATHUTILS_DEG - for backwards compat */
/* Can cast different mathutils types to this, use for generic funcs */
typedef struct {
PyObject_VAR_HEAD
float *data; /*array of data (alias), wrapped status depends on wrapped status */
PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
unsigned char wrapped; /* wrapped data type? */
} BaseMathObject;
PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * );
PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * );
void BaseMathObject_dealloc(BaseMathObject * self);
PyObject *Mathutils_Init( const char * from );
PyObject *quat_rotation(PyObject *arg1, PyObject *arg2);
@@ -75,22 +95,15 @@ struct Mathutils_Callback {
int Mathutils_RegisterCallback(Mathutils_Callback *cb);
int _Vector_ReadCallback(VectorObject *self);
int _Vector_WriteCallback(VectorObject *self);
int _Vector_ReadIndexCallback(VectorObject *self, int index);
int _Vector_WriteIndexCallback(VectorObject *self, int index);
int _BaseMathObject_ReadCallback(BaseMathObject *self);
int _BaseMathObject_WriteCallback(BaseMathObject *self);
int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index);
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
/* since this is called so often avoid where possible */
#define Vector_ReadCallback(_self) (((_self)->cb_user ? _Vector_ReadCallback(_self):1))
#define Vector_WriteCallback(_self) (((_self)->cb_user ?_Vector_WriteCallback(_self):1))
#define Vector_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _Vector_ReadIndexCallback(_self, _index):1))
#define Vector_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _Vector_WriteIndexCallback(_self, _index):1))
int _Matrix_ReadCallback(MatrixObject *self);
int _Matrix_WriteCallback(MatrixObject *self);
#define Matrix_ReadCallback(_self) (((_self)->cb_user ?_Matrix_ReadCallback(_self):1))
#define Matrix_WriteCallback(_self) (((_self)->cb_user ?_Matrix_WriteCallback(_self):1))
#define BaseMath_ReadCallback(_self) (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):1))
#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):1))
#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1))
#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1))
#endif /* EXPP_Mathutils_H */

View File

@@ -70,7 +70,7 @@ static PyObject *Euler_new(PyObject * self, PyObject * args)
PyObject *listObject = NULL;
int size, i;
float eul[3], scalar;
float eul[3];
PyObject *e;
size = PyTuple_GET_SIZE(args);
@@ -102,15 +102,13 @@ static PyObject *Euler_new(PyObject * self, PyObject * args)
return NULL;
}
scalar= (float)PyFloat_AsDouble(e);
eul[i]= (float)PyFloat_AsDouble(e);
Py_DECREF(e);
if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number
if(eul[i]==-1 && PyErr_Occurred()) { // parsed item is not a number
PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
return NULL;
}
eul[i]= scalar;
}
return newEulerObject(eul, Py_NEW);
}
@@ -123,10 +121,18 @@ static PyObject *Euler_ToQuat(EulerObject * self)
float eul[3], quat[4];
int x;
if(!BaseMath_ReadCallback(self))
return NULL;
#ifdef USE_MATHUTILS_DEG
for(x = 0; x < 3; x++) {
eul[x] = self->eul[x] * ((float)Py_PI / 180);
}
EulToQuat(eul, quat);
#else
EulToQuat(self->eul, quat);
#endif
return newQuaternionObject(quat, Py_NEW);
}
//----------------------------Euler.toMatrix()---------------------
@@ -137,10 +143,17 @@ static PyObject *Euler_ToMatrix(EulerObject * self)
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
int x;
if(!BaseMath_ReadCallback(self))
return NULL;
#ifdef USE_MATHUTILS_DEG
for(x = 0; x < 3; x++) {
eul[x] = self->eul[x] * ((float)Py_PI / 180);
}
EulToMat3(eul, (float (*)[3]) mat);
#else
EulToMat3(self->eul, (float (*)[3]) mat);
#endif
return newMatrixObject(mat, 3, 3 , Py_NEW);
}
//----------------------------Euler.unique()-----------------------
@@ -152,10 +165,15 @@ static PyObject *Euler_Unique(EulerObject * self)
double piO2 = Py_PI / 2.0f;
double Opi2 = 1.0f / pi2;
if(!BaseMath_ReadCallback(self))
return NULL;
#ifdef USE_MATHUTILS_DEG
//radians
heading = self->eul[0] * (float)Py_PI / 180;
pitch = self->eul[1] * (float)Py_PI / 180;
bank = self->eul[2] * (float)Py_PI / 180;
#endif
//wrap heading in +180 / -180
pitch += Py_PI;
@@ -186,11 +204,14 @@ static PyObject *Euler_Unique(EulerObject * self)
heading -= (floor(heading * Opi2)) * pi2;
heading -= Py_PI;
#ifdef USE_MATHUTILS_DEG
//back to degrees
self->eul[0] = (float)(heading * 180 / (float)Py_PI);
self->eul[1] = (float)(pitch * 180 / (float)Py_PI);
self->eul[2] = (float)(bank * 180 / (float)Py_PI);
#endif
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -202,6 +223,7 @@ static PyObject *Euler_Zero(EulerObject * self)
self->eul[1] = 0.0;
self->eul[2] = 0.0;
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -223,17 +245,26 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
return NULL;
}
if(!BaseMath_ReadCallback(self))
return NULL;
#ifdef USE_MATHUTILS_DEG
//covert to radians
angle *= ((float)Py_PI / 180);
for(x = 0; x < 3; x++) {
self->eul[x] *= ((float)Py_PI / 180);
}
#endif
euler_rot(self->eul, angle, *axis);
#ifdef USE_MATHUTILS_DEG
//convert back from radians
for(x = 0; x < 3; x++) {
self->eul[x] *= (180 / (float)Py_PI);
}
#endif
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -248,17 +279,27 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
return NULL;
}
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
#ifdef USE_MATHUTILS_DEG
//covert to radians
for(x = 0; x < 3; x++) {
self->eul[x] = self->eul[x] * ((float)Py_PI / 180);
eul_from_rad[x] = value->eul[x] * ((float)Py_PI / 180);
}
compatible_eul(self->eul, eul_from_rad);
#else
compatible_eul(self->eul, value->eul);
#endif
#ifdef USE_MATHUTILS_DEG
//convert back from radians
for(x = 0; x < 3; x++) {
self->eul[x] *= (180 / (float)Py_PI);
}
#endif
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -267,26 +308,21 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
// return a copy of the euler
static PyObject *Euler_copy(EulerObject * self, PyObject *args)
{
if(!BaseMath_ReadCallback(self))
return NULL;
return newEulerObject(self->eul, Py_NEW);
}
//----------------------------dealloc()(internal) ------------------
//free the py_object
static void Euler_dealloc(EulerObject * self)
{
//only free py_data
if(self->data.py_data){
PyMem_Free(self->data.py_data);
}
PyObject_DEL(self);
}
//----------------------------print object (internal)--------------
//print the object to screen
static PyObject *Euler_repr(EulerObject * self)
{
char str[64];
if(!BaseMath_ReadCallback(self))
return NULL;
sprintf(str, "[%.6f, %.6f, %.6f](euler)", self->eul[0], self->eul[1], self->eul[2]);
return PyUnicode_FromString(str);
}
@@ -297,7 +333,18 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar
EulerObject *eulA = NULL, *eulB = NULL;
int result = 0;
if (!EulerObject_Check(objectA) || !EulerObject_Check(objectB)){
if(EulerObject_Check(objectA)) {
eulA = (EulerObject*)objectA;
if(!BaseMath_ReadCallback(eulA))
return NULL;
}
if(EulerObject_Check(objectB)) {
eulB = (EulerObject*)objectB;
if(!BaseMath_ReadCallback(eulB))
return NULL;
}
if (!eulA || !eulB){
if (comparison_type == Py_NE){
Py_RETURN_TRUE;
}else{
@@ -342,13 +389,16 @@ static int Euler_len(EulerObject * self)
//sequence accessor (get)
static PyObject *Euler_item(EulerObject * self, int i)
{
if(i<0)
i= 3-i;
if(i<0) i= 3-i;
if(i < 0 || i >= 3) {
PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range");
return NULL;
}
if(!BaseMath_ReadIndexCallback(self, i))
return NULL;
return PyFloat_FromDouble(self->eul[i]);
}
@@ -363,8 +413,7 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value)
return -1;
}
if(i<0)
i= 3-i;
if(i<0) i= 3-i;
if(i < 0 || i >= 3){
PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range\n");
@@ -372,6 +421,10 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value)
}
self->eul[i] = f;
if(!BaseMath_WriteIndexCallback(self, i))
return -1;
return 0;
}
//----------------------------object[z:y]------------------------
@@ -381,6 +434,9 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end)
PyObject *list = NULL;
int count;
if(!BaseMath_ReadCallback(self))
return NULL;
CLAMP(begin, 0, 3);
if (end<0) end= 4+end;
CLAMP(end, 0, 3);
@@ -401,7 +457,10 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end,
{
int i, y, size = 0;
float eul[3];
PyObject *e, *f;
PyObject *e;
if(!BaseMath_ReadCallback(self))
return NULL;
CLAMP(begin, 0, 3);
if (end<0) end= 4+end;
@@ -421,21 +480,20 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end,
return -1;
}
f = PyNumber_Float(e);
if(f == NULL) { // parsed item not a number
Py_DECREF(e);
eul[i] = (float)PyFloat_AsDouble(e);
Py_DECREF(e);
if(eul[i]==-1 && PyErr_Occurred()) { // parsed item not a number
PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: sequence argument not a number");
return -1;
}
eul[i] = (float)PyFloat_AS_DOUBLE(f);
Py_DECREF(f);
Py_DECREF(e);
}
//parsed well - now set in vector
for(y = 0; y < 3; y++){
self->eul[begin + y] = eul[y];
}
BaseMath_WriteCallback(self);
return 0;
}
//-----------------PROTCOL DECLARATIONS--------------------------
@@ -450,79 +508,30 @@ static PySequenceMethods Euler_SeqMethods = {
};
/*
* vector axis, vector.x/y/z/w
*/
static PyObject *Euler_getAxis( EulerObject * self, void *type )
{
switch( (long)type ) {
case 'X': /* these are backwards, but that how it works */
return PyFloat_FromDouble(self->eul[0]);
case 'Y':
return PyFloat_FromDouble(self->eul[1]);
case 'Z':
return PyFloat_FromDouble(self->eul[2]);
}
PyErr_SetString(PyExc_SystemError, "corrupt euler, cannot get axis");
return NULL;
return Euler_item(self, GET_INT_FROM_POINTER(type));
}
static int Euler_setAxis( EulerObject * self, PyObject * value, void * type )
{
float param= (float)PyFloat_AsDouble( value );
if (param==-1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "expected a number for the vector axis");
return -1;
}
switch( (long)type ) {
case 'X': /* these are backwards, but that how it works */
self->eul[0]= param;
break;
case 'Y':
self->eul[1]= param;
break;
case 'Z':
self->eul[2]= param;
break;
}
return 0;
return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value);
}
static PyObject *Euler_getWrapped( VectorObject * self, void *type )
{
if (self->wrapped == Py_WRAP)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Euler_getseters[] = {
{"x",
(getter)Euler_getAxis, (setter)Euler_setAxis,
"Euler X axis",
(void *)'X'},
{"y",
(getter)Euler_getAxis, (setter)Euler_setAxis,
"Euler Y axis",
(void *)'Y'},
{"z",
(getter)Euler_getAxis, (setter)Euler_setAxis,
"Euler Z axis",
(void *)'Z'},
{"wrapped",
(getter)Euler_getWrapped, (setter)NULL,
"True when this wraps blenders internal data",
NULL},
{"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis", (void *)0},
{"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis", (void *)1},
{"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis", (void *)2},
{"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL},
{"__owner__", (getter)BaseMathObject_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -538,7 +547,7 @@ PyTypeObject euler_Type = {
"euler", //tp_name
sizeof(EulerObject), //tp_basicsize
0, //tp_itemsize
(destructor)Euler_dealloc, //tp_dealloc
(destructor)BaseMathObject_dealloc, //tp_dealloc
0, //tp_print
0, //tp_getattr
0, //tp_setattr
@@ -593,24 +602,22 @@ PyObject *newEulerObject(float *eul, int type)
int x;
self = PyObject_NEW(EulerObject, &euler_Type);
self->data.blend_data = NULL;
self->data.py_data = NULL;
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP){
self->data.blend_data = eul;
self->eul = self->data.blend_data;
self->eul = eul;
self->wrapped = Py_WRAP;
}else if (type == Py_NEW){
self->data.py_data = PyMem_Malloc(3 * sizeof(float));
self->eul = self->data.py_data;
self->eul = PyMem_Malloc(3 * sizeof(float));
if(!eul) { //new empty
for(x = 0; x < 3; x++) {
self->eul[x] = 0.0f;
}
}else{
for(x = 0; x < 3; x++){
self->eul[x] = eul[x];
}
VECCOPY(self->eul, eul);
}
self->wrapped = Py_NEW;
}else{ //bad type
@@ -618,3 +625,16 @@ PyObject *newEulerObject(float *eul, int type)
}
return (PyObject *)self;
}
PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
{
EulerObject *self= (EulerObject *)newEulerObject(NULL, Py_NEW);
if(self) {
Py_INCREF(cb_user);
self->cb_user= cb_user;
self->cb_type= (unsigned char)cb_type;
self->cb_subtype= (unsigned char)cb_subtype;
}
return self;
}

View File

@@ -40,12 +40,13 @@ extern PyTypeObject euler_Type;
typedef struct {
PyObject_VAR_HEAD
struct{
float *py_data; //python managed
float *blend_data; //blender managed
}data;
float *eul; //1D array of data (alias)
int wrapped; //is wrapped data?
float *eul; /*1D array of data */
PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
unsigned char wrapped; /* wrapped data type? */
/* end BaseMathObject */
} EulerObject;
/*struct data contains a pointer to the actual data that the
@@ -55,5 +56,6 @@ blender (stored in blend_data). This is an either/or struct not both*/
//prototypes
PyObject *newEulerObject( float *eul, int type );
PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype);
#endif /* EXPP_euler_h */

View File

@@ -39,13 +39,13 @@ int mathutils_matrix_vector_cb_index= -1;
static int mathutils_matrix_vector_check(MatrixObject *self)
{
return Matrix_ReadCallback(self);
return BaseMath_ReadCallback(self);
}
static int mathutils_matrix_vector_get(MatrixObject *self, int subtype, float *vec_from)
{
int i;
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return 0;
for(i=0; i<self->colSize; i++)
@@ -57,19 +57,19 @@ static int mathutils_matrix_vector_get(MatrixObject *self, int subtype, float *v
static int mathutils_matrix_vector_set(MatrixObject *self, int subtype, float *vec_to)
{
int i;
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return 0;
for(i=0; i<self->colSize; i++)
self->matrix[subtype][i]= vec_to[i];
Matrix_WriteCallback(self);
BaseMath_WriteCallback(self);
return 1;
}
static int mathutils_matrix_vector_get_index(MatrixObject *self, int subtype, float *vec_from, int index)
{
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return 0;
vec_from[index]= self->matrix[subtype][index];
@@ -78,12 +78,12 @@ static int mathutils_matrix_vector_get_index(MatrixObject *self, int subtype, fl
static int mathutils_matrix_vector_set_index(MatrixObject *self, int subtype, float *vec_to, int index)
{
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return 0;
self->matrix[subtype][index]= vec_to[index];
Matrix_WriteCallback(self);
BaseMath_WriteCallback(self);
return 1;
}
@@ -164,7 +164,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
argObject = PyTuple_GET_ITEM(args, 0);
if(MatrixObject_Check(argObject)){
mat = (MatrixObject*)argObject;
if(!Matrix_ReadCallback(mat))
if(!BaseMath_ReadCallback(mat))
return NULL;
argSize = mat->rowSize; //rows
@@ -225,7 +225,7 @@ static PyObject *Matrix_toQuat(MatrixObject * self)
{
float quat[4];
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -248,16 +248,23 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
EulerObject *eul_compat = NULL;
int x;
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat))
return NULL;
if(eul_compat) {
if(!BaseMath_ReadCallback(eul_compat))
return NULL;
#ifdef USE_MATHUTILS_DEG
for(x = 0; x < 3; x++) {
eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180);
}
#else
VECCOPY(eul_compatf, eul_compat->eul);
#endif
}
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -275,10 +282,12 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
PyErr_SetString(PyExc_AttributeError, "Matrix.toEuler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
return NULL;
}
#ifdef USE_MATHUTILS_DEG
/*have to convert to degrees*/
for(x = 0; x < 3; x++) {
eul[x] *= (float) (180 / Py_PI);
}
#endif
return newEulerObject(eul, Py_NEW);
}
/*---------------------------Matrix.resize4x4() ------------------*/
@@ -343,7 +352,7 @@ PyObject *Matrix_TranslationPart(MatrixObject * self)
{
float vec[4];
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if(self->colSize < 3 || self->rowSize < 4){
@@ -363,7 +372,7 @@ PyObject *Matrix_RotationPart(MatrixObject * self)
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if(self->colSize < 3 || self->rowSize < 3){
@@ -389,7 +398,7 @@ PyObject *Matrix_scalePart(MatrixObject * self)
float scale[3], rot[3];
float mat[3][3], imat[3][3], tmat[3][3];
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -422,7 +431,7 @@ PyObject *Matrix_Invert(MatrixObject * self)
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if(self->rowSize != self->colSize){
@@ -465,7 +474,7 @@ PyObject *Matrix_Invert(MatrixObject * self)
return NULL;
}
Matrix_WriteCallback(self);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -476,7 +485,7 @@ PyObject *Matrix_Determinant(MatrixObject * self)
{
float det = 0.0f;
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if(self->rowSize != self->colSize){
@@ -504,7 +513,7 @@ PyObject *Matrix_Transpose(MatrixObject * self)
{
float t = 0.0f;
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if(self->rowSize != self->colSize){
@@ -522,7 +531,7 @@ PyObject *Matrix_Transpose(MatrixObject * self)
Mat4Transp((float (*)[4])*self->matrix);
}
Matrix_WriteCallback(self);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -539,7 +548,7 @@ PyObject *Matrix_Zero(MatrixObject * self)
}
}
if(!Matrix_WriteCallback(self))
if(!BaseMath_WriteCallback(self))
return NULL;
Py_INCREF(self);
@@ -548,7 +557,7 @@ PyObject *Matrix_Zero(MatrixObject * self)
/*---------------------------Matrix.identity(() ------------------*/
PyObject *Matrix_Identity(MatrixObject * self)
{
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if(self->rowSize != self->colSize){
@@ -567,7 +576,7 @@ PyObject *Matrix_Identity(MatrixObject * self)
Mat4One((float (*)[4]) *self->matrix);
}
if(!Matrix_WriteCallback(self))
if(!BaseMath_WriteCallback(self))
return NULL;
Py_INCREF(self);
@@ -577,25 +586,12 @@ PyObject *Matrix_Identity(MatrixObject * self)
/*---------------------------Matrix.inverted() ------------------*/
PyObject *Matrix_copy(MatrixObject * self)
{
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
return (PyObject*)(MatrixObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW);
}
/*----------------------------dealloc()(internal) ----------------*/
/*free the py_object*/
static void Matrix_dealloc(MatrixObject * self)
{
PyMem_Free(self->matrix);
/*only free py_data*/
if(self->wrapped==Py_WRAP)
PyMem_Free(self->contigPtr);
Py_XDECREF(self->cb_user);
PyObject_DEL(self);
}
/*----------------------------print object (internal)-------------*/
/*print the object to screen*/
static PyObject *Matrix_repr(MatrixObject * self)
@@ -603,7 +599,7 @@ static PyObject *Matrix_repr(MatrixObject * self)
int x, y;
char buffer[48], str[1024];
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
BLI_strncpy(str,"",1024);
@@ -642,7 +638,7 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa
matA = (MatrixObject*)objectA;
matB = (MatrixObject*)objectB;
if(!Matrix_ReadCallback(matA) || !Matrix_ReadCallback(matB))
if(!BaseMath_ReadCallback(matA) || !BaseMath_ReadCallback(matB))
return NULL;
if (matA->colSize != matB->colSize || matA->rowSize != matB->rowSize){
@@ -692,7 +688,7 @@ static int Matrix_len(MatrixObject * self)
the wrapped vector gives direct access to the matrix data*/
static PyObject *Matrix_item(MatrixObject * self, int i)
{
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if(i < 0 || i >= self->rowSize) {
@@ -709,7 +705,7 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
float vec[4];
PyObject *m, *f;
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return -1;
if(i >= self->rowSize || i < 0){
@@ -746,7 +742,7 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
self->matrix[i][y] = vec[y];
}
Matrix_WriteCallback(self);
BaseMath_WriteCallback(self);
return 0;
}else{
PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: expects a sequence of column size\n");
@@ -761,7 +757,7 @@ static PyObject *Matrix_slice(MatrixObject * self, int begin, int end)
PyObject *list = NULL;
int count;
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
CLAMP(begin, 0, self->rowSize);
@@ -787,7 +783,7 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end,
PyObject *subseq;
PyObject *m;
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return -1;
CLAMP(begin, 0, self->rowSize);
@@ -848,7 +844,7 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end,
self->matrix[begin + (int)floor(x / self->colSize)][x % self->colSize] = mat[x];
}
Matrix_WriteCallback(self);
BaseMath_WriteCallback(self);
return 0;
}else{
PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation\n");
@@ -872,7 +868,7 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
return NULL;
}
if(!Matrix_ReadCallback(mat1) || !Matrix_ReadCallback(mat2))
if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2))
return NULL;
if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){
@@ -905,7 +901,7 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
return NULL;
}
if(!Matrix_ReadCallback(mat1) || !Matrix_ReadCallback(mat2))
if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2))
return NULL;
if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){
@@ -934,12 +930,12 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
if(MatrixObject_Check(m1)) {
mat1 = (MatrixObject*)m1;
if(!Matrix_ReadCallback(mat1))
if(!BaseMath_ReadCallback(mat1))
return NULL;
}
if(MatrixObject_Check(m2)) {
mat2 = (MatrixObject*)m2;
if(!Matrix_ReadCallback(mat2))
if(!BaseMath_ReadCallback(mat2))
return NULL;
}
@@ -1000,7 +996,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
}
static PyObject* Matrix_inv(MatrixObject *self)
{
if(!Matrix_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
return Matrix_Invert(self);
@@ -1052,33 +1048,15 @@ static PyObject *Matrix_getColSize( MatrixObject * self, void *type )
return PyLong_FromLong((long) self->colSize);
}
static PyObject *Matrix_getOwner( MatrixObject * self, void *type )
{
if(self->cb_user==NULL) {
Py_RETURN_NONE;
}
else {
Py_INCREF(self->cb_user);
return self->cb_user;
}
}
static PyObject *Matrix_getWrapped( MatrixObject * self, void *type )
{
if (self->wrapped == Py_WRAP)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Matrix_getseters[] = {
{"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL},
{"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL},
{"wrapped", (getter)Matrix_getWrapped, (setter)NULL, "", NULL},
{"__owner__",(getter)Matrix_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
{"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "", NULL},
{"__owner__",(getter)BaseMathObject_getOwner, (setter)NULL, "",
NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -1094,7 +1072,7 @@ PyTypeObject matrix_Type = {
"matrix", /*tp_name*/
sizeof(MatrixObject), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Matrix_dealloc, /*tp_dealloc*/
(destructor)BaseMathObject_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
@@ -1245,7 +1223,7 @@ static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject*
double dot = 0.0f;
int x, y, z = 0;
if(!Matrix_ReadCallback(mat) || !Vector_ReadCallback(vec))
if(!BaseMath_ReadCallback(mat) || !BaseMath_ReadCallback(vec))
return NULL;
if(mat->rowSize != vec->size){

View File

@@ -37,16 +37,19 @@ extern PyTypeObject matrix_Type;
#define MatrixObject_Check(v) ((v)->ob_type == &matrix_Type)
typedef float **ptRow;
typedef struct _Matrix {
PyObject_VAR_HEAD
ptRow matrix; /*ptr to the contigPtr (accessor)*/
float* contigPtr; /*1D array of data (alias)*/
PyObject* cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
unsigned char rowSize;
unsigned char colSize;
unsigned char wrapped; /*is wrapped data?*/
typedef struct _Matrix { /* keep aligned with BaseMathObject in Mathutils.h */
PyObject_VAR_HEAD
float *contigPtr; /*1D array of data (alias)*/
PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
unsigned int cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
unsigned char wrapped; /*is wrapped data?*/
/* end BaseMathObject */
unsigned char rowSize;
unsigned int colSize;
ptRow matrix; /*ptr to the contigPtr (accessor)*/
} MatrixObject;
/*struct data contains a pointer to the actual data that the

View File

@@ -77,8 +77,8 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
{
PyObject *listObject = NULL, *n, *q;
int size, i;
float quat[4], scalar;
double norm = 0.0f, angle = 0.0f;
float quat[4];
double angle = 0.0f;
size = PyTuple_GET_SIZE(args);
if (size == 1 || size == 2) { //seq?
@@ -151,28 +151,21 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
return NULL;
}
scalar = PyFloat_AsDouble(q);
if (scalar==-1 && PyErr_Occurred()) {
Py_DECREF(q);
quat[i] = PyFloat_AsDouble(q);
Py_DECREF(q);
if (quat[i]==-1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
return NULL;
}
quat[i] = scalar;
Py_DECREF(q);
}
if(size == 3){ //calculate the quat based on axis/angle
norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
quat[0] /= (float)norm;
quat[1] /= (float)norm;
quat[2] /= (float)norm;
angle = angle * (Py_PI / 180);
quat[3] =(float) (sin(angle/ 2.0f)) * quat[2];
quat[2] =(float) (sin(angle/ 2.0f)) * quat[1];
quat[1] =(float) (sin(angle/ 2.0f)) * quat[0];
quat[0] =(float) (cos(angle/ 2.0f));
}
if(size == 3) //calculate the quat based on axis/angle
#ifdef USE_MATHUTILS_DEG
AxisAngleToQuat(quat, quat, angle * (Py_PI / 180));
#else
AxisAngleToQuat(quat, quat, angle);
#endif
return newQuaternionObject(quat, Py_NEW);
}
@@ -189,33 +182,47 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat))
return NULL;
if(!BaseMath_ReadCallback(self))
return NULL;
if(eul_compat) {
float mat[3][3], eul_compatf[3];
if(!BaseMath_ReadCallback(eul_compat))
return NULL;
QuatToMat3(self->quat, mat);
#ifdef USE_MATHUTILS_DEG
for(x = 0; x < 3; x++) {
eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180);
}
QuatToMat3(self->quat, mat);
Mat3ToCompatibleEul(mat, eul, eul_compatf);
#else
Mat3ToCompatibleEul(mat, eul, eul_compat->eul);
#endif
}
else {
QuatToEul(self->quat, eul);
}
#ifdef USE_MATHUTILS_DEG
for(x = 0; x < 3; x++) {
eul[x] *= (180 / (float)Py_PI);
}
#endif
return newEulerObject(eul, Py_NEW);
}
//----------------------------Quaternion.toMatrix()------------------
//return the quat as a matrix
static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
{
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
QuatToMat3(self->quat, (float (*)[3]) mat);
float mat[9]; /* all values are set */
if(!BaseMath_ReadCallback(self))
return NULL;
QuatToMat3(self->quat, (float (*)[3]) mat);
return newMatrixObject(mat, 3, 3, Py_NEW);
}
@@ -230,6 +237,9 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va
return NULL;
}
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
QuatMul(quat, self->quat, value->quat);
return newQuaternionObject(quat, Py_NEW);
}
@@ -238,25 +248,27 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va
//return the dot quat
static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
{
int x;
double dot = 0.0;
if (!QuaternionObject_Check(value)) {
PyErr_SetString( PyExc_TypeError, "quat.dot(value): expected a quaternion argument" );
return NULL;
}
for(x = 0; x < 4; x++) {
dot += self->quat[x] * value->quat[x];
}
return PyFloat_FromDouble(dot);
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
return PyFloat_FromDouble(QuatDot(self->quat, value->quat));
}
//----------------------------Quaternion.normalize()----------------
//normalize the axis of rotation of [theta,vector]
static PyObject *Quaternion_Normalize(QuaternionObject * self)
{
if(!BaseMath_ReadCallback(self))
return NULL;
NormalQuat(self->quat);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -264,20 +276,12 @@ static PyObject *Quaternion_Normalize(QuaternionObject * self)
//invert the quat
static PyObject *Quaternion_Inverse(QuaternionObject * self)
{
double mag = 0.0f;
int x;
if(!BaseMath_ReadCallback(self))
return NULL;
for(x = 1; x < 4; x++) {
self->quat[x] = -self->quat[x];
}
for(x = 0; x < 4; x++) {
mag += (self->quat[x] * self->quat[x]);
}
mag = sqrt(mag);
for(x = 0; x < 4; x++) {
self->quat[x] /= (float)(mag * mag);
}
QuatInv(self->quat);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -285,11 +289,12 @@ static PyObject *Quaternion_Inverse(QuaternionObject * self)
//generate the identity quaternion
static PyObject *Quaternion_Identity(QuaternionObject * self)
{
self->quat[0] = 1.0;
self->quat[1] = 0.0;
self->quat[2] = 0.0;
self->quat[3] = 0.0;
if(!BaseMath_ReadCallback(self))
return NULL;
QuatOne(self->quat);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -297,10 +302,12 @@ static PyObject *Quaternion_Identity(QuaternionObject * self)
//negate the quat
static PyObject *Quaternion_Negate(QuaternionObject * self)
{
int x;
for(x = 0; x < 4; x++) {
self->quat[x] = -self->quat[x];
}
if(!BaseMath_ReadCallback(self))
return NULL;
QuatMulf(self->quat, -1.0f);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -308,10 +315,12 @@ static PyObject *Quaternion_Negate(QuaternionObject * self)
//negate the vector part
static PyObject *Quaternion_Conjugate(QuaternionObject * self)
{
int x;
for(x = 1; x < 4; x++) {
self->quat[x] = -self->quat[x];
}
if(!BaseMath_ReadCallback(self))
return NULL;
QuatConj(self->quat);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -319,18 +328,10 @@ static PyObject *Quaternion_Conjugate(QuaternionObject * self)
//return a copy of the quat
static PyObject *Quaternion_copy(QuaternionObject * self)
{
return newQuaternionObject(self->quat, Py_NEW);
}
if(!BaseMath_ReadCallback(self))
return NULL;
//----------------------------dealloc()(internal) ------------------
//free the py_object
static void Quaternion_dealloc(QuaternionObject * self)
{
//only free py_data
if(self->data.py_data){
PyMem_Free(self->data.py_data);
}
PyObject_DEL(self);
return newQuaternionObject(self->quat, Py_NEW);
}
//----------------------------print object (internal)--------------
@@ -338,6 +339,10 @@ static void Quaternion_dealloc(QuaternionObject * self)
static PyObject *Quaternion_repr(QuaternionObject * self)
{
char str[64];
if(!BaseMath_ReadCallback(self))
return NULL;
sprintf(str, "[%.6f, %.6f, %.6f, %.6f](quaternion)", self->quat[0], self->quat[1], self->quat[2], self->quat[3]);
return PyUnicode_FromString(str);
}
@@ -348,15 +353,24 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c
QuaternionObject *quatA = NULL, *quatB = NULL;
int result = 0;
if (!QuaternionObject_Check(objectA) || !QuaternionObject_Check(objectB)){
if(QuaternionObject_Check(objectA)) {
quatA = (QuaternionObject*)objectA;
if(!BaseMath_ReadCallback(quatA))
return NULL;
}
if(QuaternionObject_Check(objectB)) {
quatB = (QuaternionObject*)objectB;
if(!BaseMath_ReadCallback(quatB))
return NULL;
}
if (!quatA || !quatB){
if (comparison_type == Py_NE){
Py_RETURN_TRUE;
}else{
Py_RETURN_FALSE;
}
}
quatA = (QuaternionObject*)objectA;
quatB = (QuaternionObject*)objectB;
switch (comparison_type){
case Py_EQ:
@@ -393,10 +407,16 @@ static int Quaternion_len(QuaternionObject * self)
//sequence accessor (get)
static PyObject *Quaternion_item(QuaternionObject * self, int i)
{
if(i<0) i= 4-i;
if(i < 0 || i >= 4) {
PyErr_SetString(PyExc_IndexError, "quaternion[attribute]: array index out of range\n");
return NULL;
}
if(!BaseMath_ReadIndexCallback(self, i))
return NULL;
return PyFloat_FromDouble(self->quat[i]);
}
@@ -404,21 +424,23 @@ static PyObject *Quaternion_item(QuaternionObject * self, int i)
//sequence accessor (set)
static int Quaternion_ass_item(QuaternionObject * self, int i, PyObject * ob)
{
PyObject *f = NULL;
f = PyNumber_Float(ob);
if(f == NULL) { // parsed item not a number
PyErr_SetString(PyExc_TypeError, "quaternion[attribute] = x: argument not a number\n");
float scalar= (float)PyFloat_AsDouble(ob);
if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError, "quaternion[index] = x: index argument not a number\n");
return -1;
}
if(i<0) i= 4-i;
if(i < 0 || i >= 4){
Py_DECREF(f);
PyErr_SetString(PyExc_IndexError, "quaternion[attribute] = x: array assignment index out of range\n");
return -1;
}
self->quat[i] = (float)PyFloat_AS_DOUBLE(f);
Py_DECREF(f);
self->quat[i] = scalar;
if(!BaseMath_WriteIndexCallback(self, i))
return -1;
return 0;
}
//----------------------------object[z:y]------------------------
@@ -428,6 +450,9 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end)
PyObject *list = NULL;
int count;
if(!BaseMath_ReadCallback(self))
return NULL;
CLAMP(begin, 0, 4);
if (end<0) end= 5+end;
CLAMP(end, 0, 4);
@@ -443,12 +468,14 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end)
}
//----------------------------object[z:y]------------------------
//sequence slice (set)
static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
PyObject * seq)
static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, PyObject * seq)
{
int i, y, size = 0;
float quat[4];
PyObject *q, *f;
PyObject *q;
if(!BaseMath_ReadCallback(self))
return -1;
CLAMP(begin, 0, 4);
if (end<0) end= 5+end;
@@ -468,21 +495,19 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
return -1;
}
f = PyNumber_Float(q);
if(f == NULL) { // parsed item not a number
Py_DECREF(q);
quat[i]= (float)PyFloat_AsDouble(q);
Py_DECREF(q);
if(quat[i]==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: sequence argument not a number\n");
return -1;
}
quat[i] = (float)PyFloat_AS_DOUBLE(f);
Py_DECREF(f);
Py_DECREF(q);
}
//parsed well - now set in vector
for(y = 0; y < size; y++){
for(y = 0; y < size; y++)
self->quat[begin + y] = quat[y];
}
BaseMath_WriteCallback(self);
return 0;
}
//------------------------NUMERIC PROTOCOLS----------------------
@@ -490,7 +515,6 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
//addition
static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
{
int x;
float quat[4];
QuaternionObject *quat1 = NULL, *quat2 = NULL;
@@ -498,14 +522,13 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n");
return NULL;
}
quat1 = (QuaternionObject*)q1;
quat2 = (QuaternionObject*)q2;
for(x = 0; x < 4; x++) {
quat[x] = quat1->quat[x] + quat2->quat[x];
}
if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
return NULL;
QuatAdd(quat, quat1->quat, quat2->quat, 1.0f);
return newQuaternionObject(quat, Py_NEW);
}
//------------------------obj - obj------------------------------
@@ -524,6 +547,9 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
quat1 = (QuaternionObject*)q1;
quat2 = (QuaternionObject*)q2;
if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
return NULL;
for(x = 0; x < 4; x++) {
quat[x] = quat1->quat[x] - quat2->quat[x];
}
@@ -534,29 +560,31 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
//mulplication
static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
{
int x;
float quat[4], scalar;
double dot = 0.0f;
QuaternionObject *quat1 = NULL, *quat2 = NULL;
VectorObject *vec = NULL;
quat1 = (QuaternionObject*)q1;
quat2 = (QuaternionObject*)q2;
if(QuaternionObject_Check(q1)) {
quat1 = (QuaternionObject*)q1;
if(!BaseMath_ReadCallback(quat1))
return NULL;
}
if(QuaternionObject_Check(q2)) {
quat2 = (QuaternionObject*)q2;
if(!BaseMath_ReadCallback(quat2))
return NULL;
}
if(QuaternionObject_Check(q1) && QuaternionObject_Check(q2)) { /* QUAT*QUAT (dot product) */
for(x = 0; x < 4; x++) {
dot += quat1->quat[x] * quat1->quat[x];
}
return PyFloat_FromDouble(dot);
if(quat1 && quat2) { /* QUAT*QUAT (dot product) */
return PyFloat_FromDouble(QuatDot(quat1->quat, quat2->quat));
}
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
if(!QuaternionObject_Check(q1)) {
scalar= PyFloat_AsDouble(q1);
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */
for(x = 0; x < 4; x++) {
quat[x] = quat2->quat[x] * scalar;
}
QUATCOPY(quat, quat2->quat);
QuatMulf(quat, scalar);
return newQuaternionObject(quat, Py_NEW);
}
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type");
@@ -574,9 +602,8 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
scalar= PyFloat_AsDouble(q2);
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */
for(x = 0; x < 4; x++) {
quat[x] = quat1->quat[x] * scalar;
}
QUATCOPY(quat, quat1->quat);
QuatMulf(quat, scalar);
return newQuaternionObject(quat, Py_NEW);
}
}
@@ -625,70 +652,26 @@ static PyNumberMethods Quaternion_NumMethods = {
static PyObject *Quaternion_getAxis( QuaternionObject * self, void *type )
{
switch( (long)type ) {
case 'W':
return PyFloat_FromDouble(self->quat[0]);
case 'X':
return PyFloat_FromDouble(self->quat[1]);
case 'Y':
return PyFloat_FromDouble(self->quat[2]);
case 'Z':
return PyFloat_FromDouble(self->quat[3]);
}
PyErr_SetString(PyExc_SystemError, "corrupt quaternion, cannot get axis");
return NULL;
return Quaternion_item(self, GET_INT_FROM_POINTER(type));
}
static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * type )
{
float param= (float)PyFloat_AsDouble( value );
if (param==-1 && PyErr_Occurred()) {
PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" );
return -1;
}
switch( (long)type ) {
case 'W':
self->quat[0]= param;
break;
case 'X':
self->quat[1]= param;
break;
case 'Y':
self->quat[2]= param;
break;
case 'Z':
self->quat[3]= param;
break;
}
return 0;
}
static PyObject *Quaternion_getWrapped( QuaternionObject * self, void *type )
{
if (self->wrapped == Py_WRAP)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value);
}
static PyObject *Quaternion_getMagnitude( QuaternionObject * self, void *type )
{
double mag = 0.0;
int i;
for(i = 0; i < 4; i++) {
mag += self->quat[i] * self->quat[i];
}
return PyFloat_FromDouble(sqrt(mag));
return PyFloat_FromDouble(sqrt(QuatDot(self->quat, self->quat)));
}
static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type )
{
double ang = self->quat[0];
ang = 2 * (saacos(ang));
#ifdef USE_MATHUTILS_DEG
ang *= (180 / Py_PI);
#endif
return PyFloat_FromDouble(ang);
}
@@ -720,19 +703,19 @@ static PyGetSetDef Quaternion_getseters[] = {
{"w",
(getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
"Quaternion W value",
(void *)'W'},
(void *)0},
{"x",
(getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
"Quaternion X axis",
(void *)'X'},
(void *)1},
{"y",
(getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
"Quaternion Y axis",
(void *)'Y'},
(void *)2},
{"z",
(getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
"Quaternion Z axis",
(void *)'Z'},
(void *)3},
{"magnitude",
(getter)Quaternion_getMagnitude, (setter)NULL,
"Size of the quaternion",
@@ -746,9 +729,14 @@ static PyGetSetDef Quaternion_getseters[] = {
"quaternion axis as a vector",
NULL},
{"wrapped",
(getter)Quaternion_getWrapped, (setter)NULL,
(getter)BaseMathObject_getWrapped, (setter)NULL,
"True when this wraps blenders internal data",
NULL},
{"__owner__",
(getter)BaseMathObject_getOwner, (setter)NULL,
"Read only owner for vectors that depend on another object",
NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -765,7 +753,7 @@ PyTypeObject quaternion_Type = {
"quaternion", //tp_name
sizeof(QuaternionObject), //tp_basicsize
0, //tp_itemsize
(destructor)Quaternion_dealloc, //tp_dealloc
(destructor)BaseMathObject_dealloc, //tp_dealloc
0, //tp_print
0, //tp_getattr
0, //tp_setattr
@@ -817,26 +805,22 @@ PyTypeObject quaternion_Type = {
PyObject *newQuaternionObject(float *quat, int type)
{
QuaternionObject *self;
int x;
self = PyObject_NEW(QuaternionObject, &quaternion_Type);
self->data.blend_data = NULL;
self->data.py_data = NULL;
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP){
self->data.blend_data = quat;
self->quat = self->data.blend_data;
self->quat = quat;
self->wrapped = Py_WRAP;
}else if (type == Py_NEW){
self->data.py_data = PyMem_Malloc(4 * sizeof(float));
self->quat = self->data.py_data;
self->quat = PyMem_Malloc(4 * sizeof(float));
if(!quat) { //new empty
Quaternion_Identity(self);
Py_DECREF(self);
QuatOne(self->quat);
}else{
for(x = 0; x < 4; x++){
self->quat[x] = quat[x];
}
QUATCOPY(self->quat, quat);
}
self->wrapped = Py_NEW;
}else{ //bad type
@@ -844,3 +828,16 @@ PyObject *newQuaternionObject(float *quat, int type)
}
return (PyObject *) self;
}
PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
{
QuaternionObject *self= (QuaternionObject *)newQuaternionObject(NULL, Py_NEW);
if(self) {
Py_INCREF(cb_user);
self->cb_user= cb_user;
self->cb_type= (unsigned char)cb_type;
self->cb_subtype= (unsigned char)cb_subtype;
}
return (PyObject *)self;
}

View File

@@ -38,14 +38,15 @@ extern PyTypeObject quaternion_Type;
#define QuaternionObject_Check(v) (Py_TYPE(v) == &quaternion_Type)
typedef struct {
typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */
PyObject_VAR_HEAD
struct{
float *py_data; //python managed
float *blend_data; //blender managed
}data;
float *quat; //1D array of data (alias)
int wrapped; //is wrapped data?
float *quat; /* 1D array of data (alias) */
PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
unsigned char wrapped; /* wrapped data type? */
/* end BaseMathObject */
} QuaternionObject;
/*struct data contains a pointer to the actual data that the
@@ -55,5 +56,6 @@ blender (stored in blend_data). This is an either/or struct not both*/
//prototypes
PyObject *newQuaternionObject( float *quat, int type );
PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype);
#endif /* EXPP_quat_h */

View File

@@ -144,7 +144,7 @@ static PyObject *Vector_Zero(VectorObject * self)
self->vec[i] = 0.0f;
}
Vector_WriteCallback(self);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -155,7 +155,7 @@ static PyObject *Vector_Normalize(VectorObject * self)
int i;
float norm = 0.0f;
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
for(i = 0; i < self->size; i++) {
@@ -166,7 +166,7 @@ static PyObject *Vector_Normalize(VectorObject * self)
self->vec[i] /= norm;
}
Vector_WriteCallback(self);
BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -266,7 +266,7 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
return NULL;
}
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
if (strack) {
@@ -385,7 +385,7 @@ static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value )
return NULL;
}
if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
mirror[0] = value->vec[0];
@@ -431,7 +431,7 @@ static PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
return NULL;
}
if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW);
@@ -454,7 +454,7 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
return NULL;
}
if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
for(x = 0; x < self->size; x++) {
@@ -467,24 +467,12 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
return a copy of the vector */
static PyObject *Vector_copy(VectorObject * self)
{
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
return newVectorObject(self->vec, self->size, Py_NEW);
}
/*----------------------------dealloc()(internal) ----------------
free the py_object */
static void Vector_dealloc(VectorObject * self)
{
/* only free non wrapped */
if(self->wrapped != Py_WRAP)
PyMem_Free(self->vec);
Py_XDECREF(self->cb_user);
PyObject_DEL(self);
}
/*----------------------------print object (internal)-------------
print the object to screen */
static PyObject *Vector_repr(VectorObject * self)
@@ -492,7 +480,7 @@ static PyObject *Vector_repr(VectorObject * self)
int i;
char buffer[48], str[1024];
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
BLI_strncpy(str,"[",1024);
@@ -520,12 +508,14 @@ static int Vector_len(VectorObject * self)
sequence accessor (get)*/
static PyObject *Vector_item(VectorObject * self, int i)
{
if(i<0) i= self->size-i;
if(i < 0 || i >= self->size) {
PyErr_SetString(PyExc_IndexError,"vector[index]: out of range\n");
return NULL;
}
if(!Vector_ReadIndexCallback(self, i))
if(!BaseMath_ReadIndexCallback(self, i))
return NULL;
return PyFloat_FromDouble(self->vec[i]);
@@ -541,13 +531,15 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob)
return -1;
}
if(i<0) i= self->size-i;
if(i < 0 || i >= self->size){
PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range\n");
return -1;
}
self->vec[i] = scalar;
if(!Vector_WriteIndexCallback(self, i))
if(!BaseMath_WriteIndexCallback(self, i))
return -1;
return 0;
}
@@ -559,7 +551,7 @@ static PyObject *Vector_slice(VectorObject * self, int begin, int end)
PyObject *list = NULL;
int count;
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
CLAMP(begin, 0, self->size);
@@ -584,7 +576,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
float vec[4], scalar;
PyObject *v;
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return -1;
CLAMP(begin, 0, self->size);
@@ -620,7 +612,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
self->vec[begin + y] = vec[y];
}
if(!Vector_WriteCallback(self))
if(!BaseMath_WriteCallback(self))
return -1;
return 0;
@@ -644,7 +636,7 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2)
/* make sure v1 is always the vector */
if (vec1 && vec2 ) {
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
/*VECTOR + VECTOR*/
@@ -679,7 +671,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
/* make sure v1 is always the vector */
if (vec1 && vec2 ) {
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
/*VECTOR + VECTOR*/
@@ -694,7 +686,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
return v1;
}
Vector_WriteCallback(vec1);
BaseMath_WriteCallback(vec1);
PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n");
return NULL;
}
@@ -714,7 +706,7 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2)
vec1 = (VectorObject*)v1;
vec2 = (VectorObject*)v2;
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
if(vec1->size != vec2->size) {
@@ -747,14 +739,14 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2)
return NULL;
}
if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
for(i = 0; i < vec1->size; i++) {
vec1->vec[i] = vec1->vec[i] - vec2->vec[i];
}
Vector_WriteCallback(vec1);
BaseMath_WriteCallback(vec1);
Py_INCREF( v1 );
return v1;
}
@@ -768,12 +760,12 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
if VectorObject_Check(v1) {
vec1= (VectorObject *)v1;
if(!Vector_ReadCallback(vec1))
if(!BaseMath_ReadCallback(vec1))
return NULL;
}
if VectorObject_Check(v2) {
vec2= (VectorObject *)v2;
if(!Vector_ReadCallback(vec2))
if(!BaseMath_ReadCallback(vec2))
return NULL;
}
@@ -805,7 +797,8 @@ 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;
QuaternionObject *quat = (QuaternionObject*)v2; /* quat_rotation validates */
if(vec1->size != 3) {
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
return NULL;
@@ -835,7 +828,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
int i;
float scalar;
if(!Vector_ReadCallback(vec))
if(!BaseMath_ReadCallback(vec))
return NULL;
/* only support vec*=float and vec*=mat
@@ -845,7 +838,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
int x,y, size = vec->size;
MatrixObject *mat= (MatrixObject*)v2;
if(!Vector_ReadCallback(mat))
if(!BaseMath_ReadCallback(mat))
return NULL;
if(mat->colSize != size){
@@ -883,7 +876,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
return NULL;
}
Vector_WriteCallback(vec);
BaseMath_WriteCallback(vec);
Py_INCREF( v1 );
return v1;
}
@@ -902,7 +895,7 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2)
}
vec1 = (VectorObject*)v1; /* vector */
if(!Vector_ReadCallback(vec1))
if(!BaseMath_ReadCallback(vec1))
return NULL;
scalar = (float)PyFloat_AsDouble(v2);
@@ -930,7 +923,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
float scalar;
VectorObject *vec1 = (VectorObject*)v1;
if(!Vector_ReadCallback(vec1))
if(!BaseMath_ReadCallback(vec1))
return NULL;
scalar = (float)PyFloat_AsDouble(v2);
@@ -947,7 +940,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
vec1->vec[i] /= scalar;
}
Vector_WriteCallback(vec1);
BaseMath_WriteCallback(vec1);
Py_INCREF( v1 );
return v1;
@@ -960,7 +953,7 @@ static PyObject *Vector_neg(VectorObject *self)
int i;
float vec[4];
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
for(i = 0; i < self->size; i++){
@@ -1008,7 +1001,7 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
vecA = (VectorObject*)objectA;
vecB = (VectorObject*)objectB;
if(!Vector_ReadCallback(vecA) || !Vector_ReadCallback(vecB))
if(!BaseMath_ReadCallback(vecA) || !BaseMath_ReadCallback(vecB))
return NULL;
if (vecA->size != vecB->size){
@@ -1137,12 +1130,12 @@ static PyNumberMethods Vector_NumMethods = {
static PyObject *Vector_getAxis( VectorObject * self, void *type )
{
return Vector_item(self, (int)type);
return Vector_item(self, GET_INT_FROM_POINTER(type));
}
static int Vector_setAxis( VectorObject * self, PyObject * value, void * type )
{
return Vector_ass_item(self, (int)type, value);
return Vector_ass_item(self, GET_INT_FROM_POINTER(type), value);
}
/* vector.length */
@@ -1151,7 +1144,7 @@ static PyObject *Vector_getLength( VectorObject * self, void *type )
double dot = 0.0f;
int i;
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
for(i = 0; i < self->size; i++){
@@ -1165,7 +1158,7 @@ static int Vector_setLength( VectorObject * self, PyObject * value )
double dot = 0.0f, param;
int i;
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return -1;
param= PyFloat_AsDouble( value );
@@ -1203,30 +1196,11 @@ static int Vector_setLength( VectorObject * self, PyObject * value )
self->vec[i]= self->vec[i] / (float)dot;
}
Vector_WriteCallback(self); /* checked alredy */
BaseMath_WriteCallback(self); /* checked alredy */
return 0;
}
static PyObject *Vector_getWrapped( VectorObject * self, void *type )
{
if (self->wrapped == Py_WRAP)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
static PyObject *Vector_getOwner( VectorObject * self, void *type )
{
if(self->cb_user==NULL) {
Py_RETURN_NONE;
}
else {
Py_INCREF(self->cb_user);
return self->cb_user;
}
}
/* Get a new Vector according to the provided swizzle. This function has little
error checking, as we are in control of the inputs: the closure is set by us
in Vector_createSwizzleGetSeter. */
@@ -1237,7 +1211,7 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure)
float vec[MAX_DIMENSIONS];
unsigned int swizzleClosure;
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
/* Unpack the axes from the closure into an array. */
@@ -1277,7 +1251,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
float vecTemp[MAX_DIMENSIONS];
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return -1;
/* Check that the closure can be used with this vector: even 2D vectors have
@@ -1309,7 +1283,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
axisB++;
}
memcpy(self->vec, vecTemp, axisB * sizeof(float));
/* continue with Vector_WriteCallback at the end */
/* continue with BaseMathObject_WriteCallback at the end */
}
else if (PyList_Check(value))
{
@@ -1335,7 +1309,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
axisB++;
}
memcpy(self->vec, vecTemp, axisB * sizeof(float));
/* continue with Vector_WriteCallback at the end */
/* continue with BaseMathObject_WriteCallback at the end */
}
else if (((scalarVal = (float)PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred())==0)
{
@@ -1348,14 +1322,14 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
}
/* continue with Vector_WriteCallback at the end */
/* continue with BaseMathObject_WriteCallback at the end */
}
else {
PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." );
return -1;
}
if(!Vector_WriteCallback(vecVal))
if(!BaseMath_WriteCallback(vecVal))
return -1;
else
return 0;
@@ -1390,11 +1364,11 @@ static PyGetSetDef Vector_getseters[] = {
"Vector Length",
NULL},
{"wrapped",
(getter)Vector_getWrapped, (setter)NULL,
(getter)BaseMathObject_getWrapped, (setter)NULL,
"True when this wraps blenders internal data",
NULL},
{"__owner__",
(getter)Vector_getOwner, (setter)NULL,
(getter)BaseMathObject_getOwner, (setter)NULL,
"Read only owner for vectors that depend on another object",
NULL},
@@ -1797,13 +1771,13 @@ PyTypeObject vector_Type = {
0, /* ob_size */
#endif
/* For printing, in format "<module>.<name>" */
"Blender Vector", /* char *tp_name; */
"vector", /* char *tp_name; */
sizeof( VectorObject ), /* int tp_basicsize; */
0, /* tp_itemsize; For allocation */
/* Methods to implement standard operations */
( destructor ) Vector_dealloc,/* destructor tp_dealloc; */
( destructor ) BaseMathObject_dealloc,/* destructor tp_dealloc; */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
@@ -1920,7 +1894,7 @@ PyObject *newVectorObject(float *vec, int size, int type)
PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_subtype)
{
float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */
VectorObject *self= newVectorObject(dummy, size, Py_NEW);
VectorObject *self= (VectorObject *)newVectorObject(dummy, size, Py_NEW);
if(self) {
Py_INCREF(cb_user);
self->cb_user= cb_user;
@@ -1928,7 +1902,7 @@ PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_su
self->cb_subtype= (unsigned char)cb_subtype;
}
return self;
return (PyObject *)self;
}
//-----------------row_vector_multiplication (internal)-----------
@@ -1952,7 +1926,7 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat
}
}
if(!Vector_ReadCallback(vec) || !Matrix_ReadCallback(mat))
if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat))
return NULL;
for(x = 0; x < vec_size; x++){
@@ -1975,13 +1949,13 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat
static PyObject *Vector_Negate(VectorObject * self)
{
int i;
if(!Vector_ReadCallback(self))
if(!BaseMath_ReadCallback(self))
return NULL;
for(i = 0; i < self->size; i++)
self->vec[i] = -(self->vec[i]);
Vector_WriteCallback(self); // alredy checked for error
BaseMath_WriteCallback(self); // alredy checked for error
Py_INCREF(self);
return (PyObject*)self;

View File

@@ -37,15 +37,16 @@ extern PyTypeObject vector_Type;
#define VectorObject_Check(v) (((PyObject *)v)->ob_type == &vector_Type)
typedef struct {
typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */
PyObject_VAR_HEAD
float *vec; /*1D array of data (alias), wrapped status depends on wrapped status */
PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
unsigned char size; /* vec size 2,3 or 4 */
unsigned char wrapped; /* wrapped data type? */
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
unsigned char wrapped; /* wrapped data type? */
/* end BaseMathObject */
unsigned char size; /* vec size 2,3 or 4 */
} VectorObject;
/*prototypes*/

View File

@@ -44,8 +44,8 @@
#ifdef USE_MATHUTILS
#include "../generic/Mathutils.h" /* so we can have mathutils callbacks */
/* bpyrna vector callbacks */
static int mathutils_rna_vector_cb_index= -1; /* index for our callbacks */
/* bpyrna vector/euler/quat callbacks */
static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
static int mathutils_rna_generic_check(BPy_PropertyRNA *self)
{
@@ -88,7 +88,7 @@ static int mathutils_rna_vector_set_index(BPy_PropertyRNA *self, int subtype, fl
return 1;
}
Mathutils_Callback mathutils_rna_vector_cb = {
Mathutils_Callback mathutils_rna_array_cb = {
mathutils_rna_generic_check,
mathutils_rna_vector_get,
mathutils_rna_vector_set,
@@ -234,26 +234,43 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop);
#ifdef USE_MATHUTILS
/* return a mathutils vector where possible */
if(RNA_property_type(prop)==PROP_FLOAT) {
if(RNA_property_subtype(prop)==PROP_VECTOR) {
switch(RNA_property_subtype(prop)) {
case PROP_VECTOR:
if(len>=2 && len <= 4) {
PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_vector_cb_index, 0);
PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, 0);
Py_DECREF(ret); /* the vector owns now */
ret= vec_cb; /* return the vector instead */
}
}
else if(RNA_property_subtype(prop)==PROP_MATRIX) {
break;
case PROP_MATRIX:
if(len==16) {
PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_vector_cb_index, 0);
PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret= mat_cb; /* return the matrix instead */
}
else if (len==9) {
PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_vector_cb_index, 0);
PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret= mat_cb; /* return the matrix instead */
}
break;
case PROP_ROTATION:
if(len==3) { /* euler */
PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret= eul_cb; /* return the matrix instead */
}
else if (len==4) {
PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret= quat_cb; /* return the matrix instead */
}
break;
default:
break;
}
}
@@ -377,12 +394,15 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi
static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw);
PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
PyObject *pyrna_func_to_py(BPy_StructRNA *pyrna, FunctionRNA *func)
{
static PyMethodDef func_meth = {"<generic rna function>", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"};
PyObject *self= PyTuple_New(2);
PyObject *ret;
PyTuple_SET_ITEM(self, 0, pyrna_struct_CreatePyObject(ptr));
PyTuple_SET_ITEM(self, 0, (PyObject *)pyrna);
Py_INCREF(pyrna);
PyTuple_SET_ITEM(self, 1, PyCObject_FromVoidPtr((void *)func, NULL));
ret= PyCFunction_New(&func_meth, self);
@@ -407,23 +427,23 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
#ifdef USE_MATHUTILS
if(MatrixObject_Check(value)) {
MatrixObject *mat = (MatrixObject*)value;
if(!Matrix_ReadCallback(mat))
if(!BaseMath_ReadCallback(mat))
return -1;
py_len = mat->rowSize * mat->colSize;
} else // continue...
} else /* continue... */
#endif
if (PySequence_Check(value)) {
py_len= (int)PySequence_Length(value);
}
else {
PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array.");
PyErr_Format(PyExc_TypeError, "RNA array assignment expected a sequence instead of %s instance.", Py_TYPE(value)->tp_name);
return -1;
}
/* done getting the length */
if (py_len != len) {
PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array.");
PyErr_Format(PyExc_AttributeError, "python sequence length %d did not match the RNA array length %d.", py_len, len);
return -1;
}
@@ -493,7 +513,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
if(MatrixObject_Check(value) && RNA_property_subtype(prop) == PROP_MATRIX) {
MatrixObject *mat = (MatrixObject*)value;
memcpy(param_arr, mat->contigPtr, sizeof(float) * len);
} else // continue...
} else /* continue... */
#endif
{
/* collect the variables */
@@ -659,6 +679,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
int seq_len, i;
PyObject *item;
PointerRNA itemptr;
ListBase *lb;
CollectionPointerLink *link;
lb= (data)? (ListBase*)data: NULL;
/* convert a sequence of dict's into a collection */
if(!PySequence_Check(value)) {
@@ -674,8 +698,15 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
Py_XDECREF(item);
return -1;
}
RNA_property_collection_add(ptr, prop, &itemptr);
if(lb) {
link= MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
link->ptr= itemptr;
BLI_addtail(lb, link);
}
else
RNA_property_collection_add(ptr, prop, &itemptr);
if(pyrna_pydict_to_props(&itemptr, item, "Converting a python list to an RNA collection")==-1) {
Py_DECREF(item);
return -1;
@@ -1036,7 +1067,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
ret = pyrna_prop_to_py(&self->ptr, prop);
}
else if ((func = RNA_struct_find_function(&self->ptr, name))) {
ret = pyrna_func_to_py(&self->ptr, func);
ret = pyrna_func_to_py(self, func);
}
else if (self->ptr.type == &RNA_Context) {
PointerRNA newptr;
@@ -1362,10 +1393,21 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
break;
}
case PROP_COLLECTION:
/* XXX not supported yet
* ret = pyrna_prop_CreatePyObject(ptr, prop); */
ret = NULL;
{
ListBase *lb= (ListBase*)data;
CollectionPointerLink *link;
PyObject *linkptr;
ret = PyList_New(0);
for(link=lb->first; link; link=link->next) {
linkptr= pyrna_struct_CreatePyObject(&link->ptr);
PyList_Append(ret, linkptr);
Py_DECREF(linkptr);
}
break;
}
default:
PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
ret = NULL;
@@ -1786,7 +1828,7 @@ PyObject *BPY_rna_module( void )
PointerRNA ptr;
#ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once.
mathutils_rna_vector_cb_index= Mathutils_RegisterCallback(&mathutils_rna_vector_cb);
mathutils_rna_array_cb_index= Mathutils_RegisterCallback(&mathutils_rna_array_cb);
mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb);
#endif