Merged changes in the trunk up to revision 34670.
This commit is contained in:
@@ -37,6 +37,8 @@
|
||||
* - Mathutils.Slerp --> quat.slerp(other, fac)
|
||||
* - Mathutils.Rand: removed, use pythons random module
|
||||
* - Mathutils.RotationMatrix(angle, size, axis_flag, axis) --> Mathutils.RotationMatrix(angle, size, axis); merge axis & axis_flag args
|
||||
* - Mathutils.OrthoProjectionMatrix(plane, size, axis) --> Mathutils.OrthoProjectionMatrix(axis, size); merge axis & plane args
|
||||
* - Mathutils.ShearMatrix(plane, factor, size) --> Mathutils.ShearMatrix(plane, size, factor); swap size & factor args, match other constructors.
|
||||
* - Matrix.scalePart --> Matrix.scale_part
|
||||
* - Matrix.translationPart --> Matrix.translation_part
|
||||
* - Matrix.rotationPart --> Matrix.rotation_part
|
||||
@@ -45,10 +47,24 @@
|
||||
* - toEuler --> to_euler
|
||||
* - toQuat --> to_quat
|
||||
* - Vector.toTrackQuat --> Vector.to_track_quat
|
||||
* - Vector.rotate(axis, angle) --> rotate(other), where other can be Euler/Quaternion/Matrix.
|
||||
* - Quaternion * Quaternion --> cross product (not dot product)
|
||||
* - Euler.rotate(angle, axis) --> Euler.rotate_axis(axis, angle)
|
||||
* - Euler.unique() *removed*, not a standard function only toggled different rotations.
|
||||
*
|
||||
* - Matrix.rotation_part() -> to_3x3()
|
||||
* - Matrix.scale_part() -> to_scale()
|
||||
* - Matrix.translation_part() -> to_translation()
|
||||
* - Matrix.resize4x4() -> resize_4x4()
|
||||
* - Euler.to_quat() -> to_quaternion()
|
||||
* - Matrix.to_quat() -> to_quaternion()
|
||||
* resizing nolonger returns the resized value.
|
||||
* - Vector.resize2D -> resize_2d
|
||||
* - Vector.resize3D -> resize_3d
|
||||
* - Vector.resize4D -> resize_4d
|
||||
* added new functions.
|
||||
* - Vector.to_2d()
|
||||
* - Vector.to_3d()
|
||||
* - Vector.to_4d()
|
||||
* moved into class functions.
|
||||
* - Mathutils.RotationMatrix -> mathutils.Matrix.Rotation
|
||||
* - Mathutils.ScaleMatrix -> mathutils.Matrix.Scale
|
||||
@@ -80,11 +96,12 @@
|
||||
|
||||
//-------------------------DOC STRINGS ---------------------------
|
||||
static char M_Mathutils_doc[] =
|
||||
"This module provides access to matrices, eulers, quaternions and vectors.";
|
||||
|
||||
"This module provides access to matrices, eulers, quaternions and vectors."
|
||||
;
|
||||
static int mathutils_array_parse_fast(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
|
||||
{
|
||||
PyObject *value_fast= NULL;
|
||||
PyObject *item;
|
||||
|
||||
int i, size;
|
||||
|
||||
@@ -106,8 +123,8 @@ static int mathutils_array_parse_fast(float *array, int array_min, int array_max
|
||||
i= size;
|
||||
do {
|
||||
i--;
|
||||
if(((array[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i))) == -1.0) && PyErr_Occurred()) {
|
||||
PyErr_Format(PyExc_ValueError, "%.200s: sequence index %d is not a float", error_prefix, i);
|
||||
if(((array[i]= PyFloat_AsDouble((item= PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0) && PyErr_Occurred()) {
|
||||
PyErr_Format(PyExc_ValueError, "%.200s: sequence index %d expected a number, found '%.200s' type, ", error_prefix, i, Py_TYPE(item)->tp_name);
|
||||
Py_DECREF(value_fast);
|
||||
return -1;
|
||||
}
|
||||
@@ -148,6 +165,49 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
|
||||
}
|
||||
}
|
||||
|
||||
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
|
||||
{
|
||||
if(EulerObject_Check(value)) {
|
||||
if(!BaseMath_ReadCallback((BaseMathObject *)value)) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (QuaternionObject_Check(value)) {
|
||||
if(!BaseMath_ReadCallback((BaseMathObject *)value)) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
float tquat[4];
|
||||
normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat);
|
||||
quat_to_mat3(rmat, tquat);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (MatrixObject_Check(value)) {
|
||||
if(!BaseMath_ReadCallback((BaseMathObject *)value)) {
|
||||
return -1;
|
||||
}
|
||||
else if(((MatrixObject *)value)->colSize < 3 || ((MatrixObject *)value)->rowSize < 3) {
|
||||
PyErr_Format(PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
matrix_as_3x3(rmat, (MatrixObject *)value);
|
||||
normalize_m3(rmat);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s: expected a Euler, Quaternion or Matrix type, found %.200s", error_prefix, Py_TYPE(value)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------MATRIX FUNCTIONS--------------------
|
||||
|
||||
|
||||
|
||||
@@ -100,5 +100,6 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
|
||||
|
||||
/* utility func */
|
||||
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
|
||||
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
|
||||
|
||||
#endif /* MATHUTILS_H */
|
||||
|
||||
@@ -88,8 +88,8 @@ static char Color_copy_doc[] =
|
||||
" :return: A copy of the color.\n"
|
||||
" :rtype: :class:`Color`\n"
|
||||
"\n"
|
||||
" .. note:: use this to get a copy of a wrapped color with no reference to the original data.\n";
|
||||
|
||||
" .. note:: use this to get a copy of a wrapped color with no reference to the original data.\n"
|
||||
;
|
||||
static PyObject *Color_copy(ColorObject *self)
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
@@ -118,48 +118,40 @@ static PyObject *Color_repr(ColorObject * self)
|
||||
|
||||
//------------------------tp_richcmpr
|
||||
//returns -1 execption, 0 false, 1 true
|
||||
static PyObject* Color_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
|
||||
static PyObject* Color_richcmpr(PyObject *a, PyObject *b, int op)
|
||||
{
|
||||
ColorObject *colA = NULL, *colB = NULL;
|
||||
int result = 0;
|
||||
PyObject *res;
|
||||
int ok= -1; /* zero is true */
|
||||
|
||||
if(ColorObject_Check(objectA)) {
|
||||
colA = (ColorObject*)objectA;
|
||||
if(!BaseMath_ReadCallback(colA))
|
||||
return NULL;
|
||||
}
|
||||
if(ColorObject_Check(objectB)) {
|
||||
colB = (ColorObject*)objectB;
|
||||
if(!BaseMath_ReadCallback(colB))
|
||||
if (ColorObject_Check(a) && ColorObject_Check(b)) {
|
||||
ColorObject *colA= (ColorObject*)a;
|
||||
ColorObject *colB= (ColorObject*)b;
|
||||
|
||||
if(!BaseMath_ReadCallback(colA) || !BaseMath_ReadCallback(colB))
|
||||
return NULL;
|
||||
|
||||
ok= EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
if (!colA || !colB){
|
||||
if (comparison_type == Py_NE){
|
||||
Py_RETURN_TRUE;
|
||||
}else{
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
colA = (ColorObject*)objectA;
|
||||
colB = (ColorObject*)objectB;
|
||||
switch (op) {
|
||||
case Py_NE:
|
||||
ok = !ok; /* pass through */
|
||||
case Py_EQ:
|
||||
res = ok ? Py_False : Py_True;
|
||||
break;
|
||||
|
||||
switch (comparison_type){
|
||||
case Py_EQ:
|
||||
result = EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1);
|
||||
break;
|
||||
case Py_NE:
|
||||
result = !EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1);
|
||||
break;
|
||||
default:
|
||||
printf("The result of the comparison could not be evaluated");
|
||||
break;
|
||||
}
|
||||
if (result == 1){
|
||||
Py_RETURN_TRUE;
|
||||
}else{
|
||||
Py_RETURN_FALSE;
|
||||
case Py_LT:
|
||||
case Py_LE:
|
||||
case Py_GT:
|
||||
case Py_GE:
|
||||
res = Py_NotImplemented;
|
||||
break;
|
||||
default:
|
||||
PyErr_BadArgument();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Py_INCREF(res), res;
|
||||
}
|
||||
|
||||
//---------------------SEQUENCE PROTOCOLS------------------------
|
||||
@@ -280,7 +272,7 @@ static PyObject *Color_subscript(ColorObject *self, PyObject *item)
|
||||
return NULL;
|
||||
|
||||
if (slicelength <= 0) {
|
||||
return PyList_New(0);
|
||||
return PyTuple_New(0);
|
||||
}
|
||||
else if (step == 1) {
|
||||
return Color_slice(self, start, stop);
|
||||
@@ -461,8 +453,8 @@ static struct PyMethodDef Color_methods[] = {
|
||||
|
||||
//------------------PY_OBECT DEFINITION--------------------------
|
||||
static char color_doc[] =
|
||||
"This object gives access to Colors in Blender.";
|
||||
|
||||
"This object gives access to Colors in Blender."
|
||||
;
|
||||
PyTypeObject color_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"mathutils.Color", //tp_name
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Contributor(s): Joseph Gilbert
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
@@ -44,7 +44,7 @@
|
||||
static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *seq= NULL;
|
||||
char *order_str= NULL;
|
||||
const char *order_str= NULL;
|
||||
|
||||
float eul[EULER_SIZE]= {0.0f, 0.0f, 0.0f};
|
||||
short order= EULER_ORDER_XYZ;
|
||||
@@ -72,6 +72,13 @@ static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
return newEulerObject(eul, order, Py_NEW, type);
|
||||
}
|
||||
|
||||
/* internal use, assuem read callback is done */
|
||||
static const char *euler_order_str(EulerObject *self)
|
||||
{
|
||||
static const char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"};
|
||||
return order[self->order-EULER_ORDER_XYZ];
|
||||
}
|
||||
|
||||
short euler_order_from_string(const char *str, const char *error_prefix)
|
||||
{
|
||||
if((str[0] && str[1] && str[2] && str[3]=='\0')) {
|
||||
@@ -114,67 +121,59 @@ static PyObject *Euler_ToTupleExt(EulerObject *self, int ndigits)
|
||||
//-----------------------------METHODS----------------------------
|
||||
//return a quaternion representation of the euler
|
||||
|
||||
static char Euler_ToQuat_doc[] =
|
||||
".. method:: to_quat()\n"
|
||||
static char Euler_to_quaternion_doc[] =
|
||||
".. method:: to_quaternion()\n"
|
||||
"\n"
|
||||
" Return a quaternion representation of the euler.\n"
|
||||
"\n"
|
||||
" :return: Quaternion representation of the euler.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Euler_ToQuat(EulerObject * self)
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Euler_to_quaternion(EulerObject * self)
|
||||
{
|
||||
float quat[4];
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
if(self->order==EULER_ORDER_XYZ) eul_to_quat(quat, self->eul);
|
||||
else eulO_to_quat(quat, self->eul, self->order);
|
||||
eulO_to_quat(quat, self->eul, self->order);
|
||||
|
||||
return newQuaternionObject(quat, Py_NEW, NULL);
|
||||
}
|
||||
|
||||
//return a matrix representation of the euler
|
||||
static char Euler_ToMatrix_doc[] =
|
||||
static char Euler_to_matrix_doc[] =
|
||||
".. method:: to_matrix()\n"
|
||||
"\n"
|
||||
" Return a matrix representation of the euler.\n"
|
||||
"\n"
|
||||
" :return: A 3x3 roation matrix representation of the euler.\n"
|
||||
" :rtype: :class:`Matrix`\n";
|
||||
|
||||
static PyObject *Euler_ToMatrix(EulerObject * self)
|
||||
" :rtype: :class:`Matrix`\n"
|
||||
;
|
||||
static PyObject *Euler_to_matrix(EulerObject * self)
|
||||
{
|
||||
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float mat[9];
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
if(self->order==EULER_ORDER_XYZ) eul_to_mat3((float (*)[3])mat, self->eul);
|
||||
else eulO_to_mat3((float (*)[3])mat, self->eul, self->order);
|
||||
eulO_to_mat3((float (*)[3])mat, self->eul, self->order);
|
||||
|
||||
return newMatrixObject(mat, 3, 3 , Py_NEW, NULL);
|
||||
}
|
||||
|
||||
//sets the euler to 0,0,0
|
||||
static char Euler_Zero_doc[] =
|
||||
static char Euler_zero_doc[] =
|
||||
".. method:: zero()\n"
|
||||
"\n"
|
||||
" Set all values to zero.\n"
|
||||
"\n"
|
||||
" :return: an instance of itself\n"
|
||||
" :rtype: :class:`Euler`\n";
|
||||
|
||||
static PyObject *Euler_Zero(EulerObject * self)
|
||||
;
|
||||
static PyObject *Euler_zero(EulerObject * self)
|
||||
{
|
||||
self->eul[0] = 0.0;
|
||||
self->eul[1] = 0.0;
|
||||
self->eul[2] = 0.0;
|
||||
zero_v3(self->eul);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_INCREF(self);
|
||||
return (PyObject *)self;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static char Euler_rotate_axis_doc[] =
|
||||
@@ -186,13 +185,11 @@ static char Euler_rotate_axis_doc[] =
|
||||
" :type axis: string\n"
|
||||
" :arg angle: angle in radians.\n"
|
||||
" :type angle: float\n"
|
||||
" :return: an instance of itself\n"
|
||||
" :rtype: :class:`Euler`";
|
||||
|
||||
;
|
||||
static PyObject *Euler_rotate_axis(EulerObject * self, PyObject *args)
|
||||
{
|
||||
float angle = 0.0f;
|
||||
char *axis;
|
||||
const char *axis;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "sf:rotate", &axis, &angle)){
|
||||
PyErr_SetString(PyExc_TypeError, "euler.rotate(): expected angle (float) and axis (x,y,z)");
|
||||
@@ -206,46 +203,66 @@ static PyObject *Euler_rotate_axis(EulerObject * self, PyObject *args)
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
if(self->order == EULER_ORDER_XYZ) rotate_eul(self->eul, *axis, angle);
|
||||
else rotate_eulO(self->eul, self->order, *axis, angle);
|
||||
|
||||
rotate_eulO(self->eul, self->order, *axis, angle);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_INCREF(self);
|
||||
return (PyObject *)self;
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static char Euler_MakeCompatible_doc[] =
|
||||
static char Euler_rotate_doc[] =
|
||||
".. method:: rotate(other)\n"
|
||||
"\n"
|
||||
" Rotates the euler a by another mathutils value.\n"
|
||||
"\n"
|
||||
" :arg other: rotation component of mathutils value\n"
|
||||
" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
|
||||
;
|
||||
static PyObject *Euler_rotate(EulerObject * self, PyObject *value)
|
||||
{
|
||||
float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
if(mathutils_any_to_rotmat(other_rmat, value, "euler.rotate(value)") == -1)
|
||||
return NULL;
|
||||
|
||||
eulO_to_mat3(self_rmat, self->eul, self->order);
|
||||
mul_m3_m3m3(rmat, self_rmat, other_rmat);
|
||||
|
||||
mat3_to_compatible_eulO(self->eul, self->eul, self->order, rmat);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static char Euler_make_compatible_doc[] =
|
||||
".. method:: make_compatible(other)\n"
|
||||
"\n"
|
||||
" Make this euler compatible with another, so interpolating between them works as intended.\n"
|
||||
"\n"
|
||||
" :arg other: make compatible with this rotation.\n"
|
||||
" :type other: :class:`Euler`\n"
|
||||
" :return: an instance of itself.\n"
|
||||
" :rtype: :class:`Euler`\n"
|
||||
"\n"
|
||||
" .. note:: the order of eulers must match or an exception is raised.\n";
|
||||
|
||||
static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
||||
" .. note:: the rotation order is not taken into account for this function.\n"
|
||||
;
|
||||
static PyObject *Euler_make_compatible(EulerObject * self, PyObject *value)
|
||||
{
|
||||
if(!EulerObject_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "euler.make_compatible(euler): expected a single euler argument");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
|
||||
float teul[EULER_SIZE];
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
if(self->order != value->order) {
|
||||
PyErr_SetString(PyExc_ValueError, "euler.make_compatible(euler): rotation orders don't match");
|
||||
if(mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value, "euler.make_compatible(other), invalid 'other' arg") == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
compatible_eul(self->eul, value->eul);
|
||||
compatible_eul(self->eul, teul);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_INCREF(self);
|
||||
return (PyObject *)self;
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//----------------------------Euler.rotate()-----------------------
|
||||
@@ -259,8 +276,8 @@ static char Euler_copy_doc[] =
|
||||
" :return: A copy of the euler.\n"
|
||||
" :rtype: :class:`Euler`\n"
|
||||
"\n"
|
||||
" .. note:: use this to get a copy of a wrapped euler with no reference to the original data.\n";
|
||||
|
||||
" .. note:: use this to get a copy of a wrapped euler with no reference to the original data.\n"
|
||||
;
|
||||
static PyObject *Euler_copy(EulerObject *self)
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
@@ -275,62 +292,52 @@ static PyObject *Euler_copy(EulerObject *self)
|
||||
static PyObject *Euler_repr(EulerObject * self)
|
||||
{
|
||||
PyObject *ret, *tuple;
|
||||
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
tuple= Euler_ToTupleExt(self, -1);
|
||||
|
||||
ret= PyUnicode_FromFormat("Euler(%R)", tuple);
|
||||
ret= PyUnicode_FromFormat("Euler(%R, '%s')", tuple, euler_order_str(self));
|
||||
|
||||
Py_DECREF(tuple);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------tp_richcmpr
|
||||
//returns -1 execption, 0 false, 1 true
|
||||
static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
|
||||
static PyObject* Euler_richcmpr(PyObject *a, PyObject *b, int op)
|
||||
{
|
||||
EulerObject *eulA = NULL, *eulB = NULL;
|
||||
int result = 0;
|
||||
PyObject *res;
|
||||
int ok= -1; /* zero is true */
|
||||
|
||||
if(EulerObject_Check(objectA)) {
|
||||
eulA = (EulerObject*)objectA;
|
||||
if(!BaseMath_ReadCallback(eulA))
|
||||
return NULL;
|
||||
}
|
||||
if(EulerObject_Check(objectB)) {
|
||||
eulB = (EulerObject*)objectB;
|
||||
if(!BaseMath_ReadCallback(eulB))
|
||||
if (EulerObject_Check(a) && EulerObject_Check(b)) {
|
||||
EulerObject *eulA= (EulerObject*)a;
|
||||
EulerObject *eulB= (EulerObject*)b;
|
||||
|
||||
if(!BaseMath_ReadCallback(eulA) || !BaseMath_ReadCallback(eulB))
|
||||
return NULL;
|
||||
|
||||
ok= ((eulA->order == eulB->order) && EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ? 0 : -1;
|
||||
}
|
||||
|
||||
if (!eulA || !eulB){
|
||||
if (comparison_type == Py_NE){
|
||||
Py_RETURN_TRUE;
|
||||
}else{
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
eulA = (EulerObject*)objectA;
|
||||
eulB = (EulerObject*)objectB;
|
||||
switch (op) {
|
||||
case Py_NE:
|
||||
ok = !ok; /* pass through */
|
||||
case Py_EQ:
|
||||
res = ok ? Py_False : Py_True;
|
||||
break;
|
||||
|
||||
switch (comparison_type){
|
||||
case Py_EQ:
|
||||
result = EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1);
|
||||
break;
|
||||
case Py_NE:
|
||||
result = !EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1);
|
||||
break;
|
||||
default:
|
||||
printf("The result of the comparison could not be evaluated");
|
||||
break;
|
||||
}
|
||||
if (result == 1){
|
||||
Py_RETURN_TRUE;
|
||||
}else{
|
||||
Py_RETURN_FALSE;
|
||||
case Py_LT:
|
||||
case Py_LE:
|
||||
case Py_GT:
|
||||
case Py_GE:
|
||||
res = Py_NotImplemented;
|
||||
break;
|
||||
default:
|
||||
PyErr_BadArgument();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Py_INCREF(res), res;
|
||||
}
|
||||
|
||||
//---------------------SEQUENCE PROTOCOLS------------------------
|
||||
@@ -345,7 +352,7 @@ static int Euler_len(EulerObject *UNUSED(self))
|
||||
static PyObject *Euler_item(EulerObject * self, int i)
|
||||
{
|
||||
if(i<0) i= EULER_SIZE-i;
|
||||
|
||||
|
||||
if(i < 0 || i >= EULER_SIZE) {
|
||||
PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range");
|
||||
return NULL;
|
||||
@@ -369,12 +376,12 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject *value)
|
||||
}
|
||||
|
||||
if(i<0) i= EULER_SIZE-i;
|
||||
|
||||
|
||||
if(i < 0 || i >= EULER_SIZE){
|
||||
PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
self->eul[i] = f;
|
||||
|
||||
if(!BaseMath_WriteIndexCallback(self, i))
|
||||
@@ -451,7 +458,7 @@ static PyObject *Euler_subscript(EulerObject *self, PyObject *item)
|
||||
return NULL;
|
||||
|
||||
if (slicelength <= 0) {
|
||||
return PyList_New(0);
|
||||
return PyTuple_New(0);
|
||||
}
|
||||
else if (step == 1) {
|
||||
return Euler_slice(self, start, stop);
|
||||
@@ -533,17 +540,15 @@ static int Euler_setAxis(EulerObject *self, PyObject *value, void *type)
|
||||
/* rotation order */
|
||||
static PyObject *Euler_getOrder(EulerObject *self, void *UNUSED(closure))
|
||||
{
|
||||
const char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"};
|
||||
|
||||
if(!BaseMath_ReadCallback(self)) /* can read order too */
|
||||
return NULL;
|
||||
|
||||
return PyUnicode_FromString(order[self->order-EULER_ORDER_XYZ]);
|
||||
return PyUnicode_FromString(euler_order_str(self));
|
||||
}
|
||||
|
||||
static int Euler_setOrder(EulerObject *self, PyObject *value, void *UNUSED(closure))
|
||||
{
|
||||
char *order_str= _PyUnicode_AsString(value);
|
||||
const char *order_str= _PyUnicode_AsString(value);
|
||||
short order= euler_order_from_string(order_str, "euler.order");
|
||||
|
||||
if(order == -1)
|
||||
@@ -571,11 +576,12 @@ static PyGetSetDef Euler_getseters[] = {
|
||||
|
||||
//-----------------------METHOD DEFINITIONS ----------------------
|
||||
static struct PyMethodDef Euler_methods[] = {
|
||||
{"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc},
|
||||
{"to_matrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc},
|
||||
{"to_quat", (PyCFunction) Euler_ToQuat, METH_NOARGS, Euler_ToQuat_doc},
|
||||
{"zero", (PyCFunction) Euler_zero, METH_NOARGS, Euler_zero_doc},
|
||||
{"to_matrix", (PyCFunction) Euler_to_matrix, METH_NOARGS, Euler_to_matrix_doc},
|
||||
{"to_quaternion", (PyCFunction) Euler_to_quaternion, METH_NOARGS, Euler_to_quaternion_doc},
|
||||
{"rotate_axis", (PyCFunction) Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc},
|
||||
{"make_compatible", (PyCFunction) Euler_MakeCompatible, METH_O, Euler_MakeCompatible_doc},
|
||||
{"rotate", (PyCFunction) Euler_rotate, METH_O, Euler_rotate_doc},
|
||||
{"make_compatible", (PyCFunction) Euler_make_compatible, METH_O, Euler_make_compatible_doc},
|
||||
{"__copy__", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc},
|
||||
{"copy", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
@@ -583,8 +589,8 @@ static struct PyMethodDef Euler_methods[] = {
|
||||
|
||||
//------------------PY_OBECT DEFINITION--------------------------
|
||||
static char euler_doc[] =
|
||||
"This object gives access to Eulers in Blender.";
|
||||
|
||||
"This object gives access to Eulers in Blender."
|
||||
;
|
||||
PyTypeObject euler_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"mathutils.Euler", //tp_name
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,4 +55,6 @@ PyObject *newMatrixObject_cb(PyObject *user, int rowSize, int colSize, int cb_ty
|
||||
extern int mathutils_matrix_vector_cb_index;
|
||||
extern struct Mathutils_Callback mathutils_matrix_vector_cb;
|
||||
|
||||
void matrix_as_3x3(float mat[3][3], MatrixObject *self);
|
||||
|
||||
#endif /* MATHUTILS_MATRIX_H */
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Contributor(s): Joseph Gilbert
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
@@ -31,14 +31,26 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
||||
|
||||
#define QUAT_SIZE 4
|
||||
|
||||
#define QUAT_APPLY_TO_COPY(quat_meth_noargs, _self) \
|
||||
QuaternionObject *ret= (QuaternionObject *)Quaternion_copy(_self); \
|
||||
PyObject *ret_dummy= quat_meth_noargs(ret); \
|
||||
if(ret_dummy) { \
|
||||
Py_DECREF(ret_dummy); \
|
||||
return (PyObject *)ret; \
|
||||
} \
|
||||
else { /* error */ \
|
||||
Py_DECREF(ret); \
|
||||
return NULL; \
|
||||
} \
|
||||
|
||||
static PyObject *Quaternion_copy(QuaternionObject *self);
|
||||
|
||||
//-----------------------------METHODS------------------------------
|
||||
|
||||
/* note: BaseMath_ReadCallback must be called beforehand */
|
||||
static PyObject *Quaternion_ToTupleExt(QuaternionObject *self, int ndigits)
|
||||
static PyObject *Quaternion_to_tuple_ext(QuaternionObject *self, int ndigits)
|
||||
{
|
||||
PyObject *ret;
|
||||
int i;
|
||||
@@ -59,7 +71,7 @@ static PyObject *Quaternion_ToTupleExt(QuaternionObject *self, int ndigits)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char Quaternion_ToEuler_doc[] =
|
||||
static char Quaternion_to_euler_doc[] =
|
||||
".. method:: to_euler(order, euler_compat)\n"
|
||||
"\n"
|
||||
" Return Euler representation of the quaternion.\n"
|
||||
@@ -69,19 +81,19 @@ static char Quaternion_ToEuler_doc[] =
|
||||
" :arg euler_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.\n"
|
||||
" :type euler_compat: :class:`Euler`\n"
|
||||
" :return: Euler representation of the quaternion.\n"
|
||||
" :rtype: :class:`Euler`\n";
|
||||
|
||||
static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
" :rtype: :class:`Euler`\n"
|
||||
;
|
||||
static PyObject *Quaternion_to_euler(QuaternionObject *self, PyObject *args)
|
||||
{
|
||||
float tquat[4];
|
||||
float eul[3];
|
||||
char *order_str= NULL;
|
||||
const char *order_str= NULL;
|
||||
short order= EULER_ORDER_XYZ;
|
||||
EulerObject *eul_compat = NULL;
|
||||
|
||||
|
||||
if(!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat))
|
||||
return NULL;
|
||||
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
@@ -91,15 +103,15 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
if(order == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
normalize_qt_qt(tquat, self->quat);
|
||||
|
||||
if(eul_compat) {
|
||||
float mat[3][3];
|
||||
|
||||
|
||||
if(!BaseMath_ReadCallback(eul_compat))
|
||||
return NULL;
|
||||
|
||||
|
||||
quat_to_mat3(mat, tquat);
|
||||
|
||||
if(order == EULER_ORDER_XYZ) mat3_to_compatible_eul(eul, eul_compat->eul, mat);
|
||||
@@ -109,19 +121,19 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
if(order == EULER_ORDER_XYZ) quat_to_eul(eul, tquat);
|
||||
else quat_to_eulO(eul, order, tquat);
|
||||
}
|
||||
|
||||
|
||||
return newEulerObject(eul, order, Py_NEW, NULL);
|
||||
}
|
||||
//----------------------------Quaternion.toMatrix()------------------
|
||||
static char Quaternion_ToMatrix_doc[] =
|
||||
static char Quaternion_to_matrix_doc[] =
|
||||
".. method:: to_matrix()\n"
|
||||
"\n"
|
||||
" Return a matrix representation of the quaternion.\n"
|
||||
"\n"
|
||||
" :return: A 3x3 rotation matrix representation of the quaternion.\n"
|
||||
" :rtype: :class:`Matrix`\n";
|
||||
|
||||
static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
|
||||
" :rtype: :class:`Matrix`\n"
|
||||
;
|
||||
static PyObject *Quaternion_to_matrix(QuaternionObject *self)
|
||||
{
|
||||
float mat[9]; /* all values are set */
|
||||
|
||||
@@ -133,7 +145,7 @@ static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
|
||||
}
|
||||
|
||||
//----------------------------Quaternion.cross(other)------------------
|
||||
static char Quaternion_Cross_doc[] =
|
||||
static char Quaternion_cross_doc[] =
|
||||
".. method:: cross(other)\n"
|
||||
"\n"
|
||||
" Return the cross product of this quaternion and another.\n"
|
||||
@@ -141,26 +153,24 @@ static char Quaternion_Cross_doc[] =
|
||||
" :arg other: The other quaternion to perform the cross product with.\n"
|
||||
" :type other: :class:`Quaternion`\n"
|
||||
" :return: The cross product.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Cross(QuaternionObject *self, QuaternionObject *value)
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_cross(QuaternionObject *self, PyObject *value)
|
||||
{
|
||||
float quat[QUAT_SIZE];
|
||||
|
||||
if (!QuaternionObject_Check(value)) {
|
||||
PyErr_Format(PyExc_TypeError, "quat.cross(value): expected a quaternion argument, not %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
|
||||
float quat[QUAT_SIZE], tquat[QUAT_SIZE];
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
mul_qt_qtqt(quat, self->quat, value->quat);
|
||||
if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.cross(other), invalid 'other' arg") == -1)
|
||||
return NULL;
|
||||
|
||||
mul_qt_qtqt(quat, self->quat, tquat);
|
||||
return newQuaternionObject(quat, Py_NEW, Py_TYPE(self));
|
||||
}
|
||||
|
||||
//----------------------------Quaternion.dot(other)------------------
|
||||
static char Quaternion_Dot_doc[] =
|
||||
static char Quaternion_dot_doc[] =
|
||||
".. method:: dot(other)\n"
|
||||
"\n"
|
||||
" Return the dot product of this quaternion and another.\n"
|
||||
@@ -168,22 +178,22 @@ static char Quaternion_Dot_doc[] =
|
||||
" :arg other: The other quaternion to perform the dot product with.\n"
|
||||
" :type other: :class:`Quaternion`\n"
|
||||
" :return: The dot product.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_dot(QuaternionObject *self, PyObject *value)
|
||||
{
|
||||
if (!QuaternionObject_Check(value)) {
|
||||
PyErr_Format(PyExc_TypeError, "quat.dot(value): expected a quaternion argument, not %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
float tquat[QUAT_SIZE];
|
||||
|
||||
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
return PyFloat_FromDouble(dot_qtqt(self->quat, value->quat));
|
||||
if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.dot(other), invalid 'other' arg") == -1)
|
||||
return NULL;
|
||||
|
||||
return PyFloat_FromDouble(dot_qtqt(self->quat, tquat));
|
||||
}
|
||||
|
||||
static char Quaternion_Difference_doc[] =
|
||||
static char Quaternion_difference_doc[] =
|
||||
".. function:: difference(other)\n"
|
||||
"\n"
|
||||
" Returns a quaternion representing the rotational difference.\n"
|
||||
@@ -191,26 +201,24 @@ static char Quaternion_Difference_doc[] =
|
||||
" :arg other: second quaternion.\n"
|
||||
" :type other: :class:`Quaternion`\n"
|
||||
" :return: the rotational difference between the two quat rotations.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Difference(QuaternionObject * self, QuaternionObject * value)
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_difference(QuaternionObject *self, PyObject *value)
|
||||
{
|
||||
float quat[QUAT_SIZE];
|
||||
float tquat[QUAT_SIZE], quat[QUAT_SIZE];
|
||||
|
||||
if (!QuaternionObject_Check(value)) {
|
||||
PyErr_Format(PyExc_TypeError, "quat.difference(value): expected a quaternion argument, not %.200s", Py_TYPE(value)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
rotation_between_quats_to_quat(quat, self->quat, value->quat);
|
||||
if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.difference(other), invalid 'other' arg") == -1)
|
||||
return NULL;
|
||||
|
||||
rotation_between_quats_to_quat(quat, self->quat, tquat);
|
||||
|
||||
return newQuaternionObject(quat, Py_NEW, Py_TYPE(self));
|
||||
}
|
||||
|
||||
static char Quaternion_Slerp_doc[] =
|
||||
static char Quaternion_slerp_doc[] =
|
||||
".. function:: slerp(other, factor)\n"
|
||||
"\n"
|
||||
" Returns the interpolation of two quaternions.\n"
|
||||
@@ -220,19 +228,22 @@ static char Quaternion_Slerp_doc[] =
|
||||
" :arg factor: The interpolation value in [0.0, 1.0].\n"
|
||||
" :type factor: float\n"
|
||||
" :return: The interpolated rotation.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Slerp(QuaternionObject *self, PyObject *args)
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args)
|
||||
{
|
||||
QuaternionObject *value;
|
||||
float quat[QUAT_SIZE], fac;
|
||||
PyObject *value;
|
||||
float tquat[QUAT_SIZE], quat[QUAT_SIZE], fac;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O!f:slerp", &quaternion_Type, &value, &fac)) {
|
||||
if(!PyArg_ParseTuple(args, "Of:slerp", &value, &fac)) {
|
||||
PyErr_SetString(PyExc_TypeError, "quat.slerp(): expected Quaternion types and float");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
if(mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value, "quaternion.slerp(other), invalid 'other' arg") == -1)
|
||||
return NULL;
|
||||
|
||||
if(fac > 1.0f || fac < 0.0f) {
|
||||
@@ -240,22 +251,49 @@ static PyObject *Quaternion_Slerp(QuaternionObject *self, PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
interp_qt_qtqt(quat, self->quat, value->quat, fac);
|
||||
interp_qt_qtqt(quat, self->quat, tquat, fac);
|
||||
|
||||
return newQuaternionObject(quat, Py_NEW, Py_TYPE(self));
|
||||
}
|
||||
|
||||
static char Quaternion_rotate_doc[] =
|
||||
".. method:: rotate(other)\n"
|
||||
"\n"
|
||||
" Rotates the quaternion a by another mathutils value.\n"
|
||||
"\n"
|
||||
" :arg other: rotation component of mathutils value\n"
|
||||
" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
|
||||
;
|
||||
static PyObject *Quaternion_rotate(QuaternionObject *self, PyObject *value)
|
||||
{
|
||||
float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
|
||||
float tquat[4], length;
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
if(mathutils_any_to_rotmat(other_rmat, value, "quaternion.rotate(value)") == -1)
|
||||
return NULL;
|
||||
|
||||
length= normalize_qt_qt(tquat, self->quat);
|
||||
quat_to_mat3(self_rmat, tquat);
|
||||
mul_m3_m3m3(rmat, self_rmat, other_rmat);
|
||||
|
||||
mat3_to_quat(self->quat, rmat);
|
||||
mul_qt_fl(self->quat, length); /* maintain length after rotating */
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//----------------------------Quaternion.normalize()----------------
|
||||
//normalize the axis of rotation of [theta,vector]
|
||||
static char Quaternion_Normalize_doc[] =
|
||||
static char Quaternion_normalize_doc[] =
|
||||
".. function:: normalize()\n"
|
||||
"\n"
|
||||
" Normalize the quaternion.\n"
|
||||
"\n"
|
||||
" :return: an instance of itself.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Normalize(QuaternionObject * self)
|
||||
;
|
||||
static PyObject *Quaternion_normalize(QuaternionObject *self)
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
@@ -263,19 +301,28 @@ static PyObject *Quaternion_Normalize(QuaternionObject * self)
|
||||
normalize_qt(self->quat);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
//----------------------------Quaternion.inverse()------------------
|
||||
static char Quaternion_Inverse_doc[] =
|
||||
".. function:: inverse()\n"
|
||||
static char Quaternion_normalized_doc[] =
|
||||
".. function:: normalized()\n"
|
||||
"\n"
|
||||
" Return a new normalized quaternion.\n"
|
||||
"\n"
|
||||
" :return: a normalized copy.\n"
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_normalized(QuaternionObject *self)
|
||||
{
|
||||
QUAT_APPLY_TO_COPY(Quaternion_normalize, self);
|
||||
}
|
||||
|
||||
//----------------------------Quaternion.invert()------------------
|
||||
static char Quaternion_invert_doc[] =
|
||||
".. function:: invert()\n"
|
||||
"\n"
|
||||
" Set the quaternion to its inverse.\n"
|
||||
"\n"
|
||||
" :return: an instance of itself.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Inverse(QuaternionObject * self)
|
||||
;
|
||||
static PyObject *Quaternion_invert(QuaternionObject *self)
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
@@ -283,19 +330,31 @@ static PyObject *Quaternion_Inverse(QuaternionObject * self)
|
||||
invert_qt(self->quat);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
static char Quaternion_inverted_doc[] =
|
||||
".. function:: inverted()\n"
|
||||
"\n"
|
||||
" Return a new, inverted quaternion.\n"
|
||||
"\n"
|
||||
" :return: the inverted value.\n"
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_inverted(QuaternionObject *self)
|
||||
{
|
||||
QUAT_APPLY_TO_COPY(Quaternion_invert, self);
|
||||
}
|
||||
|
||||
//----------------------------Quaternion.identity()-----------------
|
||||
static char Quaternion_Identity_doc[] =
|
||||
static char Quaternion_identity_doc[] =
|
||||
".. function:: identity()\n"
|
||||
"\n"
|
||||
" Set the quaternion to an identity quaternion.\n"
|
||||
"\n"
|
||||
" :return: an instance of itself.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Identity(QuaternionObject * self)
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_identity(QuaternionObject *self)
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
@@ -303,19 +362,18 @@ static PyObject *Quaternion_Identity(QuaternionObject * self)
|
||||
unit_qt(self->quat);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
//----------------------------Quaternion.negate()-------------------
|
||||
static char Quaternion_Negate_doc[] =
|
||||
static char Quaternion_negate_doc[] =
|
||||
".. function:: negate()\n"
|
||||
"\n"
|
||||
" Set the quaternion to its negative.\n"
|
||||
"\n"
|
||||
" :return: an instance of itself.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Negate(QuaternionObject * self)
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_negate(QuaternionObject *self)
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
@@ -323,19 +381,15 @@ static PyObject *Quaternion_Negate(QuaternionObject * self)
|
||||
mul_qt_fl(self->quat, -1.0f);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
//----------------------------Quaternion.conjugate()----------------
|
||||
static char Quaternion_Conjugate_doc[] =
|
||||
static char Quaternion_conjugate_doc[] =
|
||||
".. function:: conjugate()\n"
|
||||
"\n"
|
||||
" Set the quaternion to its conjugate (negate x, y, z).\n"
|
||||
"\n"
|
||||
" :return: an instance of itself.\n"
|
||||
" :rtype: :class:`Quaternion`\n";
|
||||
|
||||
static PyObject *Quaternion_Conjugate(QuaternionObject * self)
|
||||
;
|
||||
static PyObject *Quaternion_conjugate(QuaternionObject *self)
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
@@ -343,9 +397,21 @@ static PyObject *Quaternion_Conjugate(QuaternionObject * self)
|
||||
conjugate_qt(self->quat);
|
||||
|
||||
(void)BaseMath_WriteCallback(self);
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
static char Quaternion_conjugated_doc[] =
|
||||
".. function:: conjugated()\n"
|
||||
"\n"
|
||||
" Return a new conjugated quaternion.\n"
|
||||
"\n"
|
||||
" :return: a new quaternion.\n"
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
;
|
||||
static PyObject *Quaternion_conjugated(QuaternionObject *self)
|
||||
{
|
||||
QUAT_APPLY_TO_COPY(Quaternion_conjugate, self);
|
||||
}
|
||||
|
||||
//----------------------------Quaternion.copy()----------------
|
||||
static char Quaternion_copy_doc[] =
|
||||
".. function:: copy()\n"
|
||||
@@ -355,8 +421,8 @@ static char Quaternion_copy_doc[] =
|
||||
" :return: A copy of the quaternion.\n"
|
||||
" :rtype: :class:`Quaternion`\n"
|
||||
"\n"
|
||||
" .. note:: use this to get a copy of a wrapped quaternion with no reference to the original data.\n";
|
||||
|
||||
" .. note:: use this to get a copy of a wrapped quaternion with no reference to the original data.\n"
|
||||
;
|
||||
static PyObject *Quaternion_copy(QuaternionObject *self)
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
@@ -367,14 +433,14 @@ static PyObject *Quaternion_copy(QuaternionObject *self)
|
||||
|
||||
//----------------------------print object (internal)--------------
|
||||
//print the object to screen
|
||||
static PyObject *Quaternion_repr(QuaternionObject * self)
|
||||
static PyObject *Quaternion_repr(QuaternionObject *self)
|
||||
{
|
||||
PyObject *ret, *tuple;
|
||||
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
|
||||
tuple= Quaternion_ToTupleExt(self, -1);
|
||||
tuple= Quaternion_to_tuple_ext(self, -1);
|
||||
|
||||
ret= PyUnicode_FromFormat("Quaternion(%R)", tuple);
|
||||
|
||||
@@ -382,53 +448,40 @@ static PyObject *Quaternion_repr(QuaternionObject * self)
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------tp_richcmpr
|
||||
//returns -1 execption, 0 false, 1 true
|
||||
static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
|
||||
static PyObject* Quaternion_richcmpr(PyObject *a, PyObject *b, int op)
|
||||
{
|
||||
QuaternionObject *quatA = NULL, *quatB = NULL;
|
||||
int result = 0;
|
||||
PyObject *res;
|
||||
int ok= -1; /* zero is true */
|
||||
|
||||
if(QuaternionObject_Check(objectA)) {
|
||||
quatA = (QuaternionObject*)objectA;
|
||||
if(!BaseMath_ReadCallback(quatA))
|
||||
return NULL;
|
||||
}
|
||||
if(QuaternionObject_Check(objectB)) {
|
||||
quatB = (QuaternionObject*)objectB;
|
||||
if(!BaseMath_ReadCallback(quatB))
|
||||
if (QuaternionObject_Check(a) && QuaternionObject_Check(b)) {
|
||||
QuaternionObject *quatA= (QuaternionObject *)a;
|
||||
QuaternionObject *quatB= (QuaternionObject *)b;
|
||||
|
||||
if(!BaseMath_ReadCallback(quatA) || !BaseMath_ReadCallback(quatB))
|
||||
return NULL;
|
||||
|
||||
ok= (EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1)) ? 0 : -1;
|
||||
}
|
||||
|
||||
if (!quatA || !quatB){
|
||||
if (comparison_type == Py_NE){
|
||||
Py_RETURN_TRUE;
|
||||
}else{
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
switch (op) {
|
||||
case Py_NE:
|
||||
ok = !ok; /* pass through */
|
||||
case Py_EQ:
|
||||
res = ok ? Py_False : Py_True;
|
||||
break;
|
||||
|
||||
case Py_LT:
|
||||
case Py_LE:
|
||||
case Py_GT:
|
||||
case Py_GE:
|
||||
res = Py_NotImplemented;
|
||||
break;
|
||||
default:
|
||||
PyErr_BadArgument();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (comparison_type){
|
||||
case Py_EQ:
|
||||
result = EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1);
|
||||
break;
|
||||
case Py_NE:
|
||||
result = EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1);
|
||||
if (result == 0){
|
||||
result = 1;
|
||||
}else{
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("The result of the comparison could not be evaluated");
|
||||
break;
|
||||
}
|
||||
if (result == 1){
|
||||
Py_RETURN_TRUE;
|
||||
}else{
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
return Py_INCREF(res), res;
|
||||
}
|
||||
|
||||
//---------------------SEQUENCE PROTOCOLS------------------------
|
||||
@@ -440,7 +493,7 @@ static int Quaternion_len(QuaternionObject *UNUSED(self))
|
||||
}
|
||||
//----------------------------object[]---------------------------
|
||||
//sequence accessor (get)
|
||||
static PyObject *Quaternion_item(QuaternionObject * self, int i)
|
||||
static PyObject *Quaternion_item(QuaternionObject *self, int i)
|
||||
{
|
||||
if(i<0) i= QUAT_SIZE-i;
|
||||
|
||||
@@ -457,7 +510,7 @@ static PyObject *Quaternion_item(QuaternionObject * self, int i)
|
||||
}
|
||||
//----------------------------object[]-------------------------
|
||||
//sequence accessor (set)
|
||||
static int Quaternion_ass_item(QuaternionObject * self, int i, PyObject * ob)
|
||||
static int Quaternion_ass_item(QuaternionObject *self, int i, PyObject *ob)
|
||||
{
|
||||
float scalar= (float)PyFloat_AsDouble(ob);
|
||||
if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
|
||||
@@ -480,7 +533,7 @@ static int Quaternion_ass_item(QuaternionObject * self, int i, PyObject * ob)
|
||||
}
|
||||
//----------------------------object[z:y]------------------------
|
||||
//sequence slice (get)
|
||||
static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end)
|
||||
static PyObject *Quaternion_slice(QuaternionObject *self, int begin, int end)
|
||||
{
|
||||
PyObject *tuple;
|
||||
int count;
|
||||
@@ -502,7 +555,7 @@ 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, size;
|
||||
float quat[QUAT_SIZE];
|
||||
@@ -517,7 +570,7 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, PyO
|
||||
|
||||
if((size=mathutils_array_parse(quat, 0, QUAT_SIZE, seq, "mathutils.Quaternion[begin:end] = []")) == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
if(size != (end - begin)){
|
||||
PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: size mismatch in slice assignment");
|
||||
return -1;
|
||||
@@ -549,7 +602,7 @@ static PyObject *Quaternion_subscript(QuaternionObject *self, PyObject *item)
|
||||
return NULL;
|
||||
|
||||
if (slicelength <= 0) {
|
||||
return PyList_New(0);
|
||||
return PyTuple_New(0);
|
||||
}
|
||||
else if (step == 1) {
|
||||
return Quaternion_slice(self, start, stop);
|
||||
@@ -598,7 +651,7 @@ static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyOb
|
||||
//------------------------NUMERIC PROTOCOLS----------------------
|
||||
//------------------------obj + obj------------------------------
|
||||
//addition
|
||||
static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
|
||||
static PyObject *Quaternion_add(PyObject *q1, PyObject *q2)
|
||||
{
|
||||
float quat[QUAT_SIZE];
|
||||
QuaternionObject *quat1 = NULL, *quat2 = NULL;
|
||||
@@ -609,7 +662,7 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
|
||||
}
|
||||
quat1 = (QuaternionObject*)q1;
|
||||
quat2 = (QuaternionObject*)q2;
|
||||
|
||||
|
||||
if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
|
||||
return NULL;
|
||||
|
||||
@@ -618,7 +671,7 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
|
||||
}
|
||||
//------------------------obj - obj------------------------------
|
||||
//subtraction
|
||||
static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
|
||||
static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2)
|
||||
{
|
||||
int x;
|
||||
float quat[QUAT_SIZE];
|
||||
@@ -628,10 +681,10 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
|
||||
PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
quat1 = (QuaternionObject*)q1;
|
||||
quat2 = (QuaternionObject*)q2;
|
||||
|
||||
|
||||
if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
|
||||
return NULL;
|
||||
|
||||
@@ -652,7 +705,7 @@ static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar)
|
||||
|
||||
//------------------------obj * obj------------------------------
|
||||
//mulplication
|
||||
static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
|
||||
static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
|
||||
{
|
||||
float quat[QUAT_SIZE], scalar;
|
||||
QuaternionObject *quat1 = NULL, *quat2 = NULL;
|
||||
@@ -748,17 +801,17 @@ static PyNumberMethods Quaternion_NumMethods = {
|
||||
0, /* nb_index */
|
||||
};
|
||||
|
||||
static PyObject *Quaternion_getAxis( QuaternionObject * self, void *type )
|
||||
static PyObject *Quaternion_getAxis( QuaternionObject *self, void *type )
|
||||
{
|
||||
return Quaternion_item(self, GET_INT_FROM_POINTER(type));
|
||||
}
|
||||
|
||||
static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * type )
|
||||
static int Quaternion_setAxis( QuaternionObject *self, PyObject *value, void *type )
|
||||
{
|
||||
return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value);
|
||||
}
|
||||
|
||||
static PyObject *Quaternion_getMagnitude(QuaternionObject * self, void *UNUSED(closure))
|
||||
static PyObject *Quaternion_getMagnitude(QuaternionObject *self, void *UNUSED(closure))
|
||||
{
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return NULL;
|
||||
@@ -766,7 +819,7 @@ static PyObject *Quaternion_getMagnitude(QuaternionObject * self, void *UNUSED(c
|
||||
return PyFloat_FromDouble(sqrt(dot_qtqt(self->quat, self->quat)));
|
||||
}
|
||||
|
||||
static PyObject *Quaternion_getAngle(QuaternionObject * self, void *UNUSED(closure))
|
||||
static PyObject *Quaternion_getAngle(QuaternionObject *self, void *UNUSED(closure))
|
||||
{
|
||||
float tquat[4];
|
||||
|
||||
@@ -777,11 +830,11 @@ static PyObject *Quaternion_getAngle(QuaternionObject * self, void *UNUSED(closu
|
||||
return PyFloat_FromDouble(2.0 * (saacos(tquat[0])));
|
||||
}
|
||||
|
||||
static int Quaternion_setAngle(QuaternionObject * self, PyObject * value, void *UNUSED(closure))
|
||||
static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UNUSED(closure))
|
||||
{
|
||||
float tquat[4];
|
||||
float len;
|
||||
|
||||
|
||||
float axis[3], angle_dummy;
|
||||
double angle;
|
||||
|
||||
@@ -807,7 +860,7 @@ static int Quaternion_setAngle(QuaternionObject * self, PyObject * value, void *
|
||||
) {
|
||||
axis[0] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
axis_angle_to_quat(self->quat, axis, angle);
|
||||
mul_qt_fl(self->quat, len);
|
||||
|
||||
@@ -820,7 +873,7 @@ static int Quaternion_setAngle(QuaternionObject * self, PyObject * value, void *
|
||||
static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *UNUSED(closure))
|
||||
{
|
||||
float tquat[4];
|
||||
|
||||
|
||||
float axis[3];
|
||||
float angle;
|
||||
|
||||
@@ -848,26 +901,17 @@ static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void *
|
||||
|
||||
float axis[3];
|
||||
float angle;
|
||||
|
||||
VectorObject *vec;
|
||||
|
||||
|
||||
if(!BaseMath_ReadCallback(self))
|
||||
return -1;
|
||||
|
||||
len= normalize_qt_qt(tquat, self->quat);
|
||||
quat_to_axis_angle(axis, &angle, tquat);
|
||||
quat_to_axis_angle(axis, &angle, tquat); /* axis value is unused */
|
||||
|
||||
if(!VectorObject_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "quaternion.axis = value: expected a 3D Vector");
|
||||
return -1;
|
||||
}
|
||||
|
||||
vec= (VectorObject *)value;
|
||||
if(!BaseMath_ReadCallback(vec))
|
||||
if (mathutils_array_parse(axis, 3, 3, value, "quat.axis = other") == -1)
|
||||
return -1;
|
||||
|
||||
axis_angle_to_quat(self->quat, vec->vec, angle);
|
||||
axis_angle_to_quat(self->quat, axis, angle);
|
||||
mul_qt_fl(self->quat, len);
|
||||
|
||||
if(!BaseMath_WriteCallback(self))
|
||||
@@ -887,7 +931,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
|
||||
PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): takes no keyword args");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if(!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle))
|
||||
return NULL;
|
||||
|
||||
@@ -912,17 +956,31 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
|
||||
|
||||
//-----------------------METHOD DEFINITIONS ----------------------
|
||||
static struct PyMethodDef Quaternion_methods[] = {
|
||||
{"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, Quaternion_Identity_doc},
|
||||
{"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, Quaternion_Negate_doc},
|
||||
{"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, Quaternion_Conjugate_doc},
|
||||
{"inverse", (PyCFunction) Quaternion_Inverse, METH_NOARGS, Quaternion_Inverse_doc},
|
||||
{"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, Quaternion_Normalize_doc},
|
||||
{"to_euler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, Quaternion_ToEuler_doc},
|
||||
{"to_matrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, Quaternion_ToMatrix_doc},
|
||||
{"cross", (PyCFunction) Quaternion_Cross, METH_O, Quaternion_Cross_doc},
|
||||
{"dot", (PyCFunction) Quaternion_Dot, METH_O, Quaternion_Dot_doc},
|
||||
{"difference", (PyCFunction) Quaternion_Difference, METH_O, Quaternion_Difference_doc},
|
||||
{"slerp", (PyCFunction) Quaternion_Slerp, METH_VARARGS, Quaternion_Slerp_doc},
|
||||
/* in place only */
|
||||
{"identity", (PyCFunction) Quaternion_identity, METH_NOARGS, Quaternion_identity_doc},
|
||||
{"negate", (PyCFunction) Quaternion_negate, METH_NOARGS, Quaternion_negate_doc},
|
||||
|
||||
/* operate on original or copy */
|
||||
{"conjugate", (PyCFunction) Quaternion_conjugate, METH_NOARGS, Quaternion_conjugate_doc},
|
||||
{"conjugated", (PyCFunction) Quaternion_conjugated, METH_NOARGS, Quaternion_conjugated_doc},
|
||||
|
||||
{"invert", (PyCFunction) Quaternion_invert, METH_NOARGS, Quaternion_invert_doc},
|
||||
{"inverted", (PyCFunction) Quaternion_inverted, METH_NOARGS, Quaternion_inverted_doc},
|
||||
|
||||
{"normalize", (PyCFunction) Quaternion_normalize, METH_NOARGS, Quaternion_normalize_doc},
|
||||
{"normalized", (PyCFunction) Quaternion_normalized, METH_NOARGS, Quaternion_normalized_doc},
|
||||
|
||||
/* return converted representation */
|
||||
{"to_euler", (PyCFunction) Quaternion_to_euler, METH_VARARGS, Quaternion_to_euler_doc},
|
||||
{"to_matrix", (PyCFunction) Quaternion_to_matrix, METH_NOARGS, Quaternion_to_matrix_doc},
|
||||
|
||||
/* operation between 2 or more types */
|
||||
{"cross", (PyCFunction) Quaternion_cross, METH_O, Quaternion_cross_doc},
|
||||
{"dot", (PyCFunction) Quaternion_dot, METH_O, Quaternion_dot_doc},
|
||||
{"difference", (PyCFunction) Quaternion_difference, METH_O, Quaternion_difference_doc},
|
||||
{"slerp", (PyCFunction) Quaternion_slerp, METH_VARARGS, Quaternion_slerp_doc},
|
||||
{"rotate", (PyCFunction) Quaternion_rotate, METH_VARARGS, Quaternion_rotate_doc},
|
||||
|
||||
{"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
|
||||
{"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
@@ -946,8 +1004,8 @@ static PyGetSetDef Quaternion_getseters[] = {
|
||||
|
||||
//------------------PY_OBECT DEFINITION--------------------------
|
||||
static char quaternion_doc[] =
|
||||
"This object gives access to Quaternions in Blender.";
|
||||
|
||||
"This object gives access to Quaternions in Blender."
|
||||
;
|
||||
PyTypeObject quaternion_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"mathutils.Quaternion", //tp_name
|
||||
@@ -1005,7 +1063,7 @@ PyTypeObject quaternion_Type = {
|
||||
PyObject *newQuaternionObject(float *quat, int type, PyTypeObject *base_type)
|
||||
{
|
||||
QuaternionObject *self;
|
||||
|
||||
|
||||
if(base_type) self = (QuaternionObject *)base_type->tp_alloc(base_type, 0);
|
||||
else self = PyObject_NEW(QuaternionObject, &quaternion_Type);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -228,6 +228,10 @@ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
|
||||
* chars since blender doesnt limit this */
|
||||
return result;
|
||||
}
|
||||
else if(PyBytes_Check(py_str)) {
|
||||
PyErr_Clear();
|
||||
return PyBytes_AS_STRING(py_str);
|
||||
}
|
||||
else {
|
||||
/* mostly copied from fileio.c's, fileio_init */
|
||||
PyObject *stringobj;
|
||||
@@ -278,6 +282,10 @@ PyObject *PyC_UnicodeFromByte(const char *str)
|
||||
for 'pickle' to work as well as strings like this...
|
||||
>> foo = 10
|
||||
>> print(__import__("__main__").foo)
|
||||
*
|
||||
* note: this overwrites __main__ which gives problems with nested calles.
|
||||
* be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
|
||||
* any chance that python is in the call stack.
|
||||
*****************************************************************************/
|
||||
PyObject *PyC_DefaultNameSpace(const char *filename)
|
||||
{
|
||||
@@ -293,6 +301,20 @@ PyObject *PyC_DefaultNameSpace(const char *filename)
|
||||
return PyModule_GetDict(mod_main);
|
||||
}
|
||||
|
||||
/* restore MUST be called after this */
|
||||
void PyC_MainModule_Backup(PyObject **main_mod)
|
||||
{
|
||||
PyInterpreterState *interp= PyThreadState_GET()->interp;
|
||||
*main_mod= PyDict_GetItemString(interp->modules, "__main__");
|
||||
Py_XINCREF(*main_mod); /* dont free */
|
||||
}
|
||||
|
||||
void PyC_MainModule_Restore(PyObject *main_mod)
|
||||
{
|
||||
PyInterpreterState *interp= PyThreadState_GET()->interp;
|
||||
PyDict_SetItemString(interp->modules, "__main__", main_mod);
|
||||
Py_XDECREF(main_mod);
|
||||
}
|
||||
|
||||
/* Would be nice if python had this built in */
|
||||
void PyC_RunQuicky(const char *filepath, int n, ...)
|
||||
|
||||
@@ -39,4 +39,7 @@ const char * PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce m
|
||||
/* name namespace function for bpy & bge */
|
||||
PyObject * PyC_DefaultNameSpace(const char *filename);
|
||||
void PyC_RunQuicky(const char *filepath, int n, ...);
|
||||
|
||||
void PyC_MainModule_Backup(PyObject **main_mod);
|
||||
void PyC_MainModule_Restore(PyObject *main_mod);
|
||||
#endif // PY_CAPI_UTILS_H
|
||||
|
||||
@@ -313,8 +313,22 @@ void BPY_python_end(void)
|
||||
|
||||
}
|
||||
|
||||
/* super annoying, undo _PyModule_Clear(), bug [#23871] */
|
||||
#define PYMODULE_CLEAR_WORKAROUND
|
||||
|
||||
#ifdef PYMODULE_CLEAR_WORKAROUND
|
||||
/* bad!, we should never do this, but currently only safe way I could find to keep namespace.
|
||||
* from being cleared. - campbell */
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *md_dict;
|
||||
/* ommit other values, we only want the dict. */
|
||||
} PyModuleObject;
|
||||
#endif
|
||||
|
||||
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
|
||||
{
|
||||
PyObject *main_mod= NULL;
|
||||
PyObject *py_dict= NULL, *py_result= NULL;
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
@@ -326,6 +340,8 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
PyC_MainModule_Backup(&main_mod);
|
||||
|
||||
if (text) {
|
||||
char fn_dummy[FILE_MAXDIR];
|
||||
bpy_text_filename_get(fn_dummy, text);
|
||||
@@ -389,25 +405,21 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
|
||||
Py_DECREF( py_result );
|
||||
}
|
||||
|
||||
/* super annoying, undo _PyModule_Clear() */
|
||||
#define PYMODULE_CLEAR_WORKAROUND
|
||||
|
||||
if(py_dict) {
|
||||
#ifdef PYMODULE_CLEAR_WORKAROUND
|
||||
PyObject *py_dict_back= PyDict_Copy(py_dict);
|
||||
Py_INCREF(py_dict);
|
||||
#endif
|
||||
/* normal */
|
||||
PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
|
||||
#ifdef PYMODULE_CLEAR_WORKAROUND
|
||||
PyDict_Clear(py_dict);
|
||||
PyDict_Update(py_dict, py_dict_back);
|
||||
Py_DECREF(py_dict);
|
||||
Py_DECREF(py_dict_back);
|
||||
PyModuleObject *mmod= (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__");
|
||||
PyObject *dict_back = mmod->md_dict;
|
||||
/* freeing the module will clear the namespace,
|
||||
* gives problems running classes defined in this namespace being used later. */
|
||||
mmod->md_dict= NULL;
|
||||
Py_DECREF(dict_back);
|
||||
#endif
|
||||
|
||||
#undef PYMODULE_CLEAR_WORKAROUND
|
||||
}
|
||||
|
||||
PyC_MainModule_Restore(main_mod);
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return (py_result != NULL);
|
||||
@@ -437,6 +449,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value)
|
||||
PyGILState_STATE gilstate;
|
||||
PyObject *py_dict, *mod, *retval;
|
||||
int error_ret = 0;
|
||||
PyObject *main_mod= NULL;
|
||||
|
||||
if (!value || !expr) return -1;
|
||||
|
||||
@@ -446,7 +459,9 @@ int BPY_button_exec(bContext *C, const char *expr, double *value)
|
||||
}
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
|
||||
PyC_MainModule_Backup(&main_mod);
|
||||
|
||||
py_dict= PyC_DefaultNameSpace("<blender button>");
|
||||
|
||||
mod = PyImport_ImportModule("math");
|
||||
@@ -497,7 +512,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value)
|
||||
BPy_errors_to_report(CTX_wm_reports(C));
|
||||
}
|
||||
|
||||
PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
|
||||
PyC_MainModule_Backup(&main_mod);
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
@@ -507,6 +522,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value)
|
||||
int BPY_string_exec(bContext *C, const char *expr)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
PyObject *main_mod= NULL;
|
||||
PyObject *py_dict, *retval;
|
||||
int error_ret = 0;
|
||||
|
||||
@@ -518,6 +534,8 @@ int BPY_string_exec(bContext *C, const char *expr)
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
PyC_MainModule_Backup(&main_mod);
|
||||
|
||||
py_dict= PyC_DefaultNameSpace("<blender string>");
|
||||
|
||||
retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict);
|
||||
@@ -531,8 +549,8 @@ int BPY_string_exec(bContext *C, const char *expr)
|
||||
Py_DECREF(retval);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(PyThreadState_GET()->interp->modules, "__main__", Py_None);
|
||||
|
||||
PyC_MainModule_Restore(main_mod);
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
return error_ret;
|
||||
|
||||
@@ -138,6 +138,11 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!pyrna_write_check()) {
|
||||
PyErr_Format(PyExc_SystemError, "Calling operator \"bpy.ops.%s\" error, can't modify blend data in this state (drawing/rendering)", opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(context_str) {
|
||||
if(RNA_enum_value_from_id(operator_context_items, context_str, &context)==0) {
|
||||
char *enum_str= BPy_enum_as_string(operator_context_items);
|
||||
@@ -226,6 +231,12 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* when calling bpy.ops.wm.read_factory_settings() bpy.data's main pointer is freed by clear_globals(),
|
||||
* further access will crash blender. setting context is not needed in this case, only calling because this
|
||||
* function corrects bpy.data (internal Main pointer) */
|
||||
BPY_modules_update(C);
|
||||
|
||||
|
||||
/* return operator_ret as a bpy enum */
|
||||
return pyrna_enum_bitfield_to_py(operator_return_items, operator_ret);
|
||||
|
||||
|
||||
@@ -83,7 +83,19 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif // USE_PEDANTIC_WRITE
|
||||
|
||||
|
||||
#ifdef USE_PEDANTIC_WRITE
|
||||
int pyrna_write_check(void)
|
||||
{
|
||||
return !rna_disallow_writes;
|
||||
}
|
||||
#else // USE_PEDANTIC_WRITE
|
||||
int pyrna_write_check(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
#endif // USE_PEDANTIC_WRITE
|
||||
|
||||
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
|
||||
@@ -423,9 +435,9 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
|
||||
int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
|
||||
{
|
||||
if(RNA_enum_value_from_id(item, identifier, value) == 0) {
|
||||
char *enum_str= BPy_enum_as_string(item);
|
||||
const char *enum_str= BPy_enum_as_string(item);
|
||||
PyErr_Format(PyExc_TypeError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
MEM_freeN((void *)enum_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -504,13 +516,13 @@ static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
|
||||
static PyObject *pyrna_struct_str( BPy_StructRNA *self )
|
||||
{
|
||||
PyObject *ret;
|
||||
char *name;
|
||||
const char *name;
|
||||
|
||||
/* print name if available */
|
||||
name= RNA_struct_name_get_alloc(&self->ptr, NULL, FALSE);
|
||||
if(name) {
|
||||
ret= PyUnicode_FromFormat( "<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name);
|
||||
MEM_freeN(name);
|
||||
MEM_freeN((void *)name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -528,11 +540,11 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
|
||||
}
|
||||
else {
|
||||
PyObject *ret;
|
||||
char *path;
|
||||
const char *path;
|
||||
path= RNA_path_from_ID_to_struct(&self->ptr);
|
||||
if(path) {
|
||||
ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path);
|
||||
MEM_freeN(path);
|
||||
MEM_freeN((void *)path);
|
||||
}
|
||||
else { /* cant find, print something sane */
|
||||
ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_struct_identifier(self->ptr.type));
|
||||
@@ -546,7 +558,7 @@ static PyObject *pyrna_prop_str( BPy_PropertyRNA *self )
|
||||
{
|
||||
PyObject *ret;
|
||||
PointerRNA ptr;
|
||||
char *name;
|
||||
const char *name;
|
||||
const char *type_id= NULL;
|
||||
char type_fmt[64]= "";
|
||||
int type= RNA_property_type(self->prop);
|
||||
@@ -579,7 +591,7 @@ static PyObject *pyrna_prop_str( BPy_PropertyRNA *self )
|
||||
|
||||
if(name) {
|
||||
ret= PyUnicode_FromFormat( "<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name);
|
||||
MEM_freeN(name);
|
||||
MEM_freeN((void *)name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -591,7 +603,7 @@ static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
|
||||
{
|
||||
ID *id= self->ptr.id.data;
|
||||
PyObject *ret;
|
||||
char *path;
|
||||
const char *path;
|
||||
|
||||
if(id == NULL)
|
||||
return pyrna_prop_str(self); /* fallback */
|
||||
@@ -599,7 +611,7 @@ static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
|
||||
path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
|
||||
if(path) {
|
||||
ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path);
|
||||
MEM_freeN(path);
|
||||
MEM_freeN((void *)path);
|
||||
}
|
||||
else { /* cant find, print something sane */
|
||||
ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_property_identifier(self->prop));
|
||||
@@ -670,7 +682,7 @@ static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
|
||||
|
||||
static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix)
|
||||
{
|
||||
char *param= _PyUnicode_AsString(item);
|
||||
const char *param= _PyUnicode_AsString(item);
|
||||
|
||||
if (param==NULL) {
|
||||
const char *enum_str= pyrna_enum_as_string(ptr, prop);
|
||||
@@ -702,7 +714,7 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_
|
||||
*r_value= 0;
|
||||
|
||||
while (_PySet_NextEntry(value, &pos, &key, &hash)) {
|
||||
char *param= _PyUnicode_AsString(key);
|
||||
const char *param= _PyUnicode_AsString(key);
|
||||
|
||||
if(param==NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s expected a string. found a %.200s", error_prefix, Py_TYPE(key)->tp_name);
|
||||
@@ -800,7 +812,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
|
||||
ret= PyUnicode_FromString(item->identifier);
|
||||
}
|
||||
else {
|
||||
char *ptr_name= RNA_struct_name_get_alloc(ptr, NULL, FALSE);
|
||||
const char *ptr_name= RNA_struct_name_get_alloc(ptr, NULL, FALSE);
|
||||
|
||||
/* prefer not fail silently incase of api errors, maybe disable it later */
|
||||
printf("RNA Warning: Current value \"%d\" matches no enum in '%s', '%s', '%s'\n", val, RNA_struct_identifier(ptr->type), ptr_name, RNA_property_identifier(prop));
|
||||
@@ -812,9 +824,9 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
|
||||
#endif
|
||||
|
||||
if(ptr_name)
|
||||
MEM_freeN(ptr_name);
|
||||
MEM_freeN((void *)ptr_name);
|
||||
|
||||
ret = PyUnicode_FromString( "" );
|
||||
ret = PyUnicode_FromString("");
|
||||
}
|
||||
|
||||
if(free)
|
||||
@@ -851,7 +863,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
case PROP_STRING:
|
||||
{
|
||||
int subtype= RNA_property_subtype(prop);
|
||||
char *buf;
|
||||
const char *buf;
|
||||
buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
|
||||
#ifdef USE_STRING_COERCE
|
||||
/* only file paths get special treatment, they may contain non utf-8 chars */
|
||||
@@ -864,7 +876,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
#else // USE_STRING_COERCE
|
||||
ret= PyUnicode_FromString(buf);
|
||||
#endif // USE_STRING_COERCE
|
||||
MEM_freeN(buf);
|
||||
MEM_freeN((void *)buf);
|
||||
break;
|
||||
}
|
||||
case PROP_ENUM:
|
||||
@@ -1277,7 +1289,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
|
||||
|
||||
if(pyrna_pydict_to_props(&itemptr, item, 1, "Converting a python list to an RNA collection")==-1) {
|
||||
PyObject *msg= PyC_ExceptionBuffer();
|
||||
char *msg_char= _PyUnicode_AsString(msg);
|
||||
const char *msg_char= _PyUnicode_AsString(msg);
|
||||
|
||||
PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s error converting a member of a collection from a dicts into an RNA collection, failed with: %s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), msg_char);
|
||||
|
||||
@@ -1899,7 +1911,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value
|
||||
PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */
|
||||
|
||||
/* key in dict style check */
|
||||
char *keyname = _PyUnicode_AsString(value);
|
||||
const char *keyname = _PyUnicode_AsString(value);
|
||||
|
||||
if(keyname==NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string");
|
||||
@@ -1915,7 +1927,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value
|
||||
static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
|
||||
{
|
||||
IDProperty *group;
|
||||
char *name = _PyUnicode_AsString(value);
|
||||
const char *name = _PyUnicode_AsString(value);
|
||||
|
||||
if (!name) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy_struct.__contains__: expected a string");
|
||||
@@ -1978,7 +1990,7 @@ static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key )
|
||||
{
|
||||
/* mostly copied from BPy_IDGroup_Map_GetItem */
|
||||
IDProperty *group, *idprop;
|
||||
char *name= _PyUnicode_AsString(key);
|
||||
const char *name= _PyUnicode_AsString(key);
|
||||
|
||||
if(RNA_struct_idprops_check(self->ptr.type)==0) {
|
||||
PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties");
|
||||
@@ -2114,7 +2126,7 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
|
||||
|
||||
/* for keyframes and drivers */
|
||||
static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path,
|
||||
char **path_full, int *index)
|
||||
const char **path_full, int *index)
|
||||
{
|
||||
const int is_idbase= RNA_struct_is_ID(ptr->type);
|
||||
PropertyRNA *prop;
|
||||
@@ -2189,10 +2201,10 @@ static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefi
|
||||
|
||||
/* internal use for insert and delete */
|
||||
static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
|
||||
char **path_full, int *index, float *cfra, char **group_name) /* return values */
|
||||
const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
|
||||
{
|
||||
static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
|
||||
char *path;
|
||||
const char *path;
|
||||
|
||||
/* note, parse_str MUST start with 's|ifs' */
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
|
||||
@@ -2226,10 +2238,10 @@ static char pyrna_struct_keyframe_insert_doc[] =
|
||||
static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
/* args, pyrna_struct_keyframe_parse handles these */
|
||||
char *path_full= NULL;
|
||||
const char *path_full= NULL;
|
||||
int index= -1;
|
||||
float cfra= FLT_MAX;
|
||||
char *group_name= NULL;
|
||||
const char *group_name= NULL;
|
||||
|
||||
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
|
||||
return NULL;
|
||||
@@ -2241,7 +2253,7 @@ static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *arg
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
|
||||
result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
|
||||
MEM_freeN(path_full);
|
||||
MEM_freeN((void *)path_full);
|
||||
|
||||
if(BPy_reports_to_error(&reports, TRUE))
|
||||
return NULL;
|
||||
@@ -2269,10 +2281,10 @@ static char pyrna_struct_keyframe_delete_doc[] =
|
||||
static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
/* args, pyrna_struct_keyframe_parse handles these */
|
||||
char *path_full= NULL;
|
||||
const char *path_full= NULL;
|
||||
int index= -1;
|
||||
float cfra= FLT_MAX;
|
||||
char *group_name= NULL;
|
||||
const char *group_name= NULL;
|
||||
|
||||
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_delete()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
|
||||
return NULL;
|
||||
@@ -2284,7 +2296,7 @@ static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *arg
|
||||
BKE_reports_init(&reports, RPT_STORE);
|
||||
|
||||
result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
|
||||
MEM_freeN(path_full);
|
||||
MEM_freeN((void *)path_full);
|
||||
|
||||
if(BPy_reports_to_error(&reports, TRUE))
|
||||
return NULL;
|
||||
@@ -2308,7 +2320,7 @@ static char pyrna_struct_driver_add_doc[] =
|
||||
|
||||
static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
char *path, *path_full;
|
||||
const char *path, *path_full;
|
||||
int index= -1;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
|
||||
@@ -2359,7 +2371,7 @@ static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MEM_freeN(path_full);
|
||||
MEM_freeN((void *)path_full);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2380,7 +2392,7 @@ static char pyrna_struct_driver_remove_doc[] =
|
||||
|
||||
static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
char *path, *path_full;
|
||||
const char *path, *path_full;
|
||||
int index= -1;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
|
||||
@@ -2397,7 +2409,7 @@ static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
|
||||
|
||||
result= ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
|
||||
|
||||
MEM_freeN(path_full);
|
||||
MEM_freeN((void *)path_full);
|
||||
|
||||
if(BPy_reports_to_error(&reports, TRUE))
|
||||
return NULL;
|
||||
@@ -2418,7 +2430,7 @@ static char pyrna_struct_is_property_set_doc[] =
|
||||
static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
char *name;
|
||||
const char *name;
|
||||
int ret;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
|
||||
@@ -2458,7 +2470,7 @@ static char pyrna_struct_is_property_hidden_doc[] =
|
||||
static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
char *name;
|
||||
const char *name;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name))
|
||||
return NULL;
|
||||
@@ -2483,7 +2495,7 @@ static char pyrna_struct_path_resolve_doc[] =
|
||||
|
||||
static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
char *path;
|
||||
const char *path;
|
||||
PyObject *coerce= Py_True;
|
||||
PointerRNA r_ptr;
|
||||
PropertyRNA *r_prop;
|
||||
@@ -2534,8 +2546,8 @@ static char pyrna_struct_path_from_id_doc[] =
|
||||
|
||||
static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
char *name= NULL;
|
||||
char *path;
|
||||
const char *name= NULL;
|
||||
const char *path;
|
||||
PropertyRNA *prop;
|
||||
PyObject *ret;
|
||||
|
||||
@@ -2562,7 +2574,7 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
|
||||
}
|
||||
|
||||
ret= PyUnicode_FromString(path);
|
||||
MEM_freeN(path);
|
||||
MEM_freeN((void *)path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2577,7 +2589,7 @@ static char pyrna_prop_path_from_id_doc[] =
|
||||
|
||||
static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
|
||||
{
|
||||
char *path;
|
||||
const char *path;
|
||||
PropertyRNA *prop = self->prop;
|
||||
PyObject *ret;
|
||||
|
||||
@@ -2589,7 +2601,7 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
|
||||
}
|
||||
|
||||
ret= PyUnicode_FromString(path);
|
||||
MEM_freeN(path);
|
||||
MEM_freeN((void *)path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2724,7 +2736,7 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
|
||||
//---------------getattr--------------------------------------------
|
||||
static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
const char *name = _PyUnicode_AsString(pyname);
|
||||
PyObject *ret;
|
||||
PropertyRNA *prop;
|
||||
FunctionRNA *func;
|
||||
@@ -2902,13 +2914,13 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb
|
||||
}
|
||||
else {
|
||||
/* remove existing property if its set or we also end up with confusement */
|
||||
char *attr_str= _PyUnicode_AsString(attr);
|
||||
const char *attr_str= _PyUnicode_AsString(attr);
|
||||
RNA_def_property_free_identifier(srna, attr_str); /* ignore on failier */
|
||||
}
|
||||
}
|
||||
else { /* __delattr__ */
|
||||
/* first find if this is a registered property */
|
||||
char *attr_str= _PyUnicode_AsString(attr);
|
||||
const char *attr_str= _PyUnicode_AsString(attr);
|
||||
int ret= RNA_def_property_free_identifier(srna, attr_str);
|
||||
if (ret == -1) {
|
||||
PyErr_Format(PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str);
|
||||
@@ -2922,7 +2934,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb
|
||||
|
||||
static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObject *value )
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
const char *name = _PyUnicode_AsString(pyname);
|
||||
PropertyRNA *prop= NULL;
|
||||
|
||||
#ifdef USE_PEDANTIC_WRITE
|
||||
@@ -3005,7 +3017,7 @@ static PyObject *pyrna_prop_array_getattro( BPy_PropertyRNA *self, PyObject *pyn
|
||||
|
||||
static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject *pyname )
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
const char *name = _PyUnicode_AsString(pyname);
|
||||
|
||||
if(name == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string");
|
||||
@@ -3040,7 +3052,7 @@ static PyObject *pyrna_prop_collection_getattro( BPy_PropertyRNA *self, PyObject
|
||||
//--------------- setattr-------------------------------------------
|
||||
static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyname, PyObject *value )
|
||||
{
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
const char *name = _PyUnicode_AsString(pyname);
|
||||
PropertyRNA *prop;
|
||||
PointerRNA r_ptr;
|
||||
|
||||
@@ -3225,7 +3237,7 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
IDProperty *group, *idprop;
|
||||
|
||||
char *key;
|
||||
const char *key;
|
||||
PyObject* def = Py_None;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
|
||||
@@ -3267,7 +3279,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
|
||||
{
|
||||
PointerRNA newptr;
|
||||
|
||||
char *key;
|
||||
const char *key;
|
||||
PyObject* def = Py_None;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def))
|
||||
@@ -3279,7 +3291,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
|
||||
return Py_INCREF(def), def;
|
||||
}
|
||||
|
||||
static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
|
||||
static void foreach_attr_type( BPy_PropertyRNA *self, const char *attr,
|
||||
/* values to assign */
|
||||
RawPropertyType *raw_type, int *attr_tot, int *attr_signed )
|
||||
{
|
||||
@@ -3304,7 +3316,7 @@ static int foreach_parse_args(
|
||||
BPy_PropertyRNA *self, PyObject *args,
|
||||
|
||||
/*values to assign */
|
||||
char **attr, PyObject **seq, int *tot, int *size, RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
|
||||
const char **attr, PyObject **seq, int *tot, int *size, RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
|
||||
{
|
||||
#if 0
|
||||
int array_tot;
|
||||
@@ -3386,7 +3398,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
|
||||
void *array= NULL;
|
||||
|
||||
/* get/set both take the same args currently */
|
||||
char *attr;
|
||||
const char *attr;
|
||||
PyObject *seq;
|
||||
int tot, size, attr_tot, attr_signed;
|
||||
RawPropertyType raw_type;
|
||||
@@ -3986,7 +3998,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
|
||||
DynStr *bad_args= BLI_dynstr_new();
|
||||
DynStr *good_args= BLI_dynstr_new();
|
||||
|
||||
char *arg_name, *bad_args_str, *good_args_str;
|
||||
const char *arg_name, *bad_args_str, *good_args_str;
|
||||
int found= FALSE, first= TRUE;
|
||||
|
||||
while (PyDict_Next(kw, &pos, &key, &value)) {
|
||||
@@ -4039,8 +4051,8 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
|
||||
|
||||
BLI_dynstr_free(bad_args);
|
||||
BLI_dynstr_free(good_args);
|
||||
MEM_freeN(bad_args_str);
|
||||
MEM_freeN(good_args_str);
|
||||
MEM_freeN((void *)bad_args_str);
|
||||
MEM_freeN((void *)good_args_str);
|
||||
|
||||
err= -1;
|
||||
}
|
||||
@@ -4868,7 +4880,7 @@ static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA *self, PyObject *pynam
|
||||
{
|
||||
PointerRNA newptr;
|
||||
PyObject *ret;
|
||||
char *name= _PyUnicode_AsString(pyname);
|
||||
const char *name= _PyUnicode_AsString(pyname);
|
||||
|
||||
if(name == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "bpy.types: __getattr__ must be a string");
|
||||
@@ -5304,8 +5316,6 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void BPY_modules_update(bContext *C); //XXX temp solution
|
||||
|
||||
/* TODO - multiple return values like with rna functions */
|
||||
static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
|
||||
{
|
||||
@@ -5324,8 +5334,9 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
#ifdef USE_PEDANTIC_WRITE
|
||||
const char *func_id= RNA_function_identifier(func);
|
||||
/* testing, for correctness, not operator and not draw function */
|
||||
const short is_readonly= strstr("draw", RNA_function_identifier(func)) || !RNA_struct_is_a(ptr->type, &RNA_Operator);
|
||||
const short is_readonly= strstr("draw", func_id) || /*strstr("render", func_id) ||*/ !RNA_struct_is_a(ptr->type, &RNA_Operator);
|
||||
#endif
|
||||
|
||||
py_class= RNA_struct_py_type_get(ptr->type);
|
||||
|
||||
@@ -108,4 +108,8 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr,
|
||||
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop);
|
||||
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value);
|
||||
|
||||
int pyrna_write_check(void);
|
||||
|
||||
void BPY_modules_update(struct bContext *C); //XXX temp solution
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#
|
||||
# #**** END GPL LICENSE BLOCK #****
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
if 1:
|
||||
# Print once every 1000
|
||||
GEN_PATH = True
|
||||
@@ -37,6 +39,7 @@ else:
|
||||
|
||||
seek_count = [0]
|
||||
|
||||
|
||||
def seek(r, txt, recurs):
|
||||
|
||||
seek_count[0] += 1
|
||||
@@ -71,52 +74,60 @@ def seek(r, txt, recurs):
|
||||
print(txt + ' -> "' + str(r) + '"')
|
||||
return
|
||||
|
||||
try: keys = r.keys()
|
||||
except: keys = None
|
||||
try:
|
||||
keys = r.keys()
|
||||
except:
|
||||
keys = None
|
||||
|
||||
if keys != None:
|
||||
if PRINT_DATA:
|
||||
print(txt + '.keys() - ' + str(r.keys()))
|
||||
|
||||
try: __members__ = dir(r)
|
||||
except: __members__ = []
|
||||
try:
|
||||
__members__ = dir(r)
|
||||
except:
|
||||
__members__ = []
|
||||
|
||||
for item in __members__:
|
||||
if item.startswith('__'):
|
||||
if item.startswith("__"):
|
||||
continue
|
||||
|
||||
if GEN_PATH: newtxt = txt + '.' + item
|
||||
if GEN_PATH:
|
||||
newtxt = txt + '.' + item
|
||||
|
||||
if item == 'rna_type' and VERBOSE_TYPE==False: # just avoid because it spits out loads of data
|
||||
if item == 'rna_type' and VERBOSE_TYPE == False: # just avoid because it spits out loads of data
|
||||
continue
|
||||
|
||||
try: value = getattr(r, item)
|
||||
except: value = None
|
||||
|
||||
seek( value, newtxt, recurs + 1)
|
||||
value = getattr(r, item, None)
|
||||
|
||||
seek(value, newtxt, recurs + 1)
|
||||
|
||||
if keys:
|
||||
for k in keys:
|
||||
if GEN_PATH: newtxt = txt + '["' + k + '"]'
|
||||
seek(r.__getitem__(k), newtxt, recurs+1)
|
||||
if GEN_PATH:
|
||||
newtxt = txt + '["' + k + '"]'
|
||||
seek(r.__getitem__(k), newtxt, recurs + 1)
|
||||
|
||||
else:
|
||||
try: length = len( r )
|
||||
except: length = 0
|
||||
try:
|
||||
length = len(r)
|
||||
except:
|
||||
length = 0
|
||||
|
||||
if VERBOSE==False and length >= 4:
|
||||
for i in (0, length-1):
|
||||
if i>0:
|
||||
if VERBOSE == False and length >= 4:
|
||||
for i in (0, length - 1):
|
||||
if i > 0:
|
||||
if PRINT_DATA:
|
||||
print((' '*len(txt)) + ' ... skipping '+str(length-2)+' items ...')
|
||||
print((" " * len(txt)) + " ... skipping " + str(length - 2) + " items ...")
|
||||
|
||||
if GEN_PATH: newtxt = txt + '[' + str(i) + ']'
|
||||
seek(r[i], newtxt, recurs+1)
|
||||
if GEN_PATH:
|
||||
newtxt = txt + '[' + str(i) + ']'
|
||||
seek(r[i], newtxt, recurs + 1)
|
||||
else:
|
||||
for i in range(length):
|
||||
if GEN_PATH: newtxt = txt + '[' + str(i) + ']'
|
||||
seek(r[i], newtxt, recurs+1)
|
||||
if GEN_PATH:
|
||||
newtxt = txt + '[' + str(i) + ']'
|
||||
seek(r[i], newtxt, recurs + 1)
|
||||
|
||||
seek(bpy.data, 'bpy.data', 0)
|
||||
# seek(bpy.types, 'bpy.types', 0)
|
||||
|
||||
Reference in New Issue
Block a user