[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28420] trunk/blender/source/blender/ python: rna/python mathutils module

Campbell Barton ideasman42 at gmail.com
Mon Apr 26 01:33:09 CEST 2010


Revision: 28420
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28420
Author:   campbellbarton
Date:     2010-04-26 01:33:09 +0200 (Mon, 26 Apr 2010)

Log Message:
-----------
rna/python mathutils module
- return euler rotation values from rna now have correct rotation order.
- mathutils.Euler stored rotation order off by 1. (didnt work at all)
- Euler/Quat/Color sliceing working again.

Modified Paths:
--------------
    trunk/blender/source/blender/python/generic/mathutils_color.c
    trunk/blender/source/blender/python/generic/mathutils_euler.c
    trunk/blender/source/blender/python/generic/mathutils_matrix.c
    trunk/blender/source/blender/python/generic/mathutils_quat.c
    trunk/blender/source/blender/python/intern/bpy_rna.c

Modified: trunk/blender/source/blender/python/generic/mathutils_color.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_color.c	2010-04-25 21:13:42 UTC (rev 28419)
+++ trunk/blender/source/blender/python/generic/mathutils_color.c	2010-04-25 23:33:09 UTC (rev 28420)
@@ -27,6 +27,8 @@
 #include "BLI_math.h"
 #include "BKE_utildefines.h"
 
+#define COLOR_SIZE 3
+
 //----------------------------------mathutils.Color() -------------------
 //makes a new color for you to play with
 static PyObject *Color_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
@@ -37,7 +39,7 @@
 	case 0:
 		break;
 	case 1:
-		if((mathutils_array_parse(col, 3, 3, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) == -1)
+		if((mathutils_array_parse(col, COLOR_SIZE, COLOR_SIZE, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) == -1)
 			return NULL;
 		break;
 	default:
@@ -55,15 +57,15 @@
 	PyObject *ret;
 	int i;
 
-	ret= PyTuple_New(3);
+	ret= PyTuple_New(COLOR_SIZE);
 
 	if(ndigits >= 0) {
-		for(i= 0; i < 3; i++) {
+		for(i= 0; i < COLOR_SIZE; i++) {
 			PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->col[i], ndigits)));
 		}
 	}
 	else {
-		for(i= 0; i < 3; i++) {
+		for(i= 0; i < COLOR_SIZE; i++) {
 			PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->col[i]));
 		}
 	}
@@ -137,10 +139,10 @@
 
 	switch (comparison_type){
 		case Py_EQ:
-			result = EXPP_VectorsAreEqual(colA->col, colB->col, 3, 1);
+			result = EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1);
 			break;
 		case Py_NE:
-			result = !EXPP_VectorsAreEqual(colA->col, colB->col, 3, 1);
+			result = !EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1);
 			break;
 		default:
 			printf("The result of the comparison could not be evaluated");
@@ -158,15 +160,15 @@
 //sequence length
 static int Color_len(ColorObject * self)
 {
-	return 3;
+	return COLOR_SIZE;
 }
 //----------------------------object[]---------------------------
 //sequence accessor (get)
 static PyObject *Color_item(ColorObject * self, int i)
 {
-	if(i<0) i= 3-i;
+	if(i<0) i= COLOR_SIZE-i;
 
-	if(i < 0 || i >= 3) {
+	if(i < 0 || i >= COLOR_SIZE) {
 		PyErr_SetString(PyExc_IndexError, "color[attribute]: array index out of range");
 		return NULL;
 	}
@@ -188,9 +190,9 @@
 		return -1;
 	}
 
-	if(i<0) i= 3-i;
+	if(i<0) i= COLOR_SIZE-i;
 
-	if(i < 0 || i >= 3){
+	if(i < 0 || i >= COLOR_SIZE){
 		PyErr_SetString(PyExc_IndexError, "color[attribute] = x: array assignment index out of range\n");
 		return -1;
 	}
@@ -212,9 +214,9 @@
 	if(!BaseMath_ReadCallback(self))
 		return NULL;
 
-	CLAMP(begin, 0, 3);
-	if (end<0) end= 4+end;
-	CLAMP(end, 0, 3);
+	CLAMP(begin, 0, COLOR_SIZE);
+	if (end<0) end= (COLOR_SIZE + 1) + end;
+	CLAMP(end, 0, COLOR_SIZE);
 	begin = MIN2(begin,end);
 
 	list = PyList_New(end - begin);
@@ -227,61 +229,116 @@
 }
 //----------------------------object[z:y]------------------------
 //sequence slice (set)
-static int Color_ass_slice(ColorObject * self, int begin, int end,
-				 PyObject * seq)
+static int Color_ass_slice(ColorObject * self, int begin, int end, PyObject * seq)
 {
-	int i, y, size = 0;
-	float col[3];
-	PyObject *e;
+	int i, size;
+	float col[COLOR_SIZE];
 
 	if(!BaseMath_ReadCallback(self))
 		return -1;
 
-	CLAMP(begin, 0, 3);
-	if (end<0) end= 4+end;
-	CLAMP(end, 0, 3);
+	CLAMP(begin, 0, COLOR_SIZE);
+	if (end<0) end= (COLOR_SIZE + 1) + end;
+	CLAMP(end, 0, COLOR_SIZE);
 	begin = MIN2(begin,end);
 
-	size = PySequence_Length(seq);
+	if((size=mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) == -1)
+		return -1;
+
 	if(size != (end - begin)){
 		PyErr_SetString(PyExc_TypeError, "color[begin:end] = []: size mismatch in slice assignment");
 		return -1;
 	}
 
-	for (i = 0; i < size; i++) {
-		e = PySequence_GetItem(seq, i);
-		if (e == NULL) { // Failed to read sequence
-			PyErr_SetString(PyExc_RuntimeError, "color[begin:end] = []: unable to read sequence");
-			return -1;
+	for(i= 0; i < COLOR_SIZE; i++)
+		self->col[begin + i] = col[i];
+
+	BaseMath_WriteCallback(self);
+	return 0;
+}
+
+static PyObject *Color_subscript(ColorObject *self, PyObject *item)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i;
+		i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += COLOR_SIZE;
+		return Color_item(self, i);
+	} else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0)
+			return NULL;
+
+		if (slicelength <= 0) {
+			return PyList_New(0);
 		}
+		else if (step == 1) {
+			return Color_slice(self, start, stop);
+		}
+		else {
+			PyErr_SetString(PyExc_TypeError, "slice steps not supported with eulers");
+			return NULL;
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+				 "euler indices must be integers, not %.200s",
+				 item->ob_type->tp_name);
+		return NULL;
+	}
+}
 
-		col[i] = (float)PyFloat_AsDouble(e);
-		Py_DECREF(e);
+static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *value)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return -1;
+		if (i < 0)
+			i += COLOR_SIZE;
+		return Color_ass_item(self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
 
-		if(col[i]==-1 && PyErr_Occurred()) { // parsed item not a number
-			PyErr_SetString(PyExc_TypeError, "color[begin:end] = []: sequence argument not a number");
+		if (PySlice_GetIndicesEx((PySliceObject*)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0)
 			return -1;
+
+		if (step == 1)
+			return Color_ass_slice(self, start, stop, value);
+		else {
+			PyErr_SetString(PyExc_TypeError, "slice steps not supported with euler");
+			return -1;
 		}
 	}
-	//parsed well - now set in vector
-	for(y = 0; y < 3; y++){
-		self->col[begin + y] = col[y];
+	else {
+		PyErr_Format(PyExc_TypeError,
+				 "euler indices must be integers, not %.200s",
+				 item->ob_type->tp_name);
+		return -1;
 	}
+}
 
-	BaseMath_WriteCallback(self);
-	return 0;
-}
 //-----------------PROTCOL DECLARATIONS--------------------------
 static PySequenceMethods Color_SeqMethods = {
-	(lenfunc) Color_len,						/* sq_length */
-	(binaryfunc) 0,								/* sq_concat */
-	(ssizeargfunc) 0,								/* sq_repeat */
-	(ssizeargfunc) Color_item,					/* sq_item */
-	(ssizessizeargfunc) Color_slice,				/* sq_slice */
-	(ssizeobjargproc) Color_ass_item,				/* sq_ass_item */
-	(ssizessizeobjargproc) Color_ass_slice,			/* sq_ass_slice */
+	(lenfunc) Color_len,					/* sq_length */
+	(binaryfunc) 0,							/* sq_concat */
+	(ssizeargfunc) 0,						/* sq_repeat */
+	(ssizeargfunc) Color_item,				/* sq_item */
+	(ssizessizeargfunc) NULL,				/* sq_slice, deprecated */
+	(ssizeobjargproc) Color_ass_item,		/* sq_ass_item */
+	(ssizessizeobjargproc) NULL,			/* sq_ass_slice, deprecated */
 };
 
+static PyMappingMethods Color_AsMapping = {
+	(lenfunc)Color_len,
+	(binaryfunc)Color_subscript,
+	(objobjargproc)Color_ass_subscript
+};
 
 /* color channel, vector.r/g/b */
 static PyObject *Color_getChannel( ColorObject * self, void *type )
@@ -414,7 +471,7 @@
 	(reprfunc) Color_repr,			//tp_repr
 	0,				//tp_as_number
 	&Color_SeqMethods,				//tp_as_sequence
-	0,								//tp_as_mapping
+	&Color_AsMapping,				//tp_as_mapping
 	0,								//tp_hash
 	0,								//tp_call
 	0,								//tp_str
@@ -458,7 +515,6 @@
 PyObject *newColorObject(float *col, int type, PyTypeObject *base_type)
 {
 	ColorObject *self;
-	int x;
 
 	if(base_type)	self = (ColorObject *)base_type->tp_alloc(base_type, 0);
 	else			self = PyObject_NEW(ColorObject, &color_Type);
@@ -470,17 +526,17 @@
 	if(type == Py_WRAP){
 		self->col = col;
 		self->wrapped = Py_WRAP;
-	}else if (type == Py_NEW){
-		self->col = PyMem_Malloc(3 * sizeof(float));
-		if(!col) { //new empty
-			for(x = 0; x < 3; x++) {
-				self->col[x] = 0.0f;
-			}
-		}else{
-			VECCOPY(self->col, col);
-		}
+	}
+	else if (type == Py_NEW){
+		self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float));
+		if(col)
+			copy_v3_v3(self->col, col);
+		else
+			zero_v3(self->col);
+
 		self->wrapped = Py_NEW;
-	}else{ //bad type
+	}
+	else {
 		return NULL;
 	}
 

Modified: trunk/blender/source/blender/python/generic/mathutils_euler.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_euler.c	2010-04-25 21:13:42 UTC (rev 28419)
+++ trunk/blender/source/blender/python/generic/mathutils_euler.c	2010-04-25 23:33:09 UTC (rev 28420)
@@ -35,6 +35,8 @@
 #include "BLO_sys_types.h"
 #endif
 
+#define EULER_SIZE 3
+
 //----------------------------------mathutils.Euler() -------------------
 //makes a new euler for you to play with
 static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
@@ -42,8 +44,8 @@
 	PyObject *seq= NULL;
 	char *order_str= NULL;
 
-	float eul[3]= {0.0f, 0.0f, 0.0f};
-	short order= 0;
+	float eul[EULER_SIZE]= {0.0f, 0.0f, 0.0f};
+	short order= EULER_ORDER_XYZ;
 
 	if(!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str))
 		return NULL;
@@ -56,7 +58,7 @@
 			return NULL;
 		/* intentionally pass through */
 	case 1:
-		if (mathutils_array_parse(eul, 3, 3, seq, "mathutils.Euler()") == -1)
+		if (mathutils_array_parse(eul, EULER_SIZE, EULER_SIZE, seq, "mathutils.Euler()") == -1)
 			return NULL;
 		break;
 	}
@@ -67,12 +69,12 @@
 {
 	if((str[0] && str[1] && str[2] && str[3]=='\0')) {
 		switch(*((int32_t *)str)) {
-			case 'X'|'Y'<<8|'Z'<<16:	return 0;
-			case 'X'|'Z'<<8|'Y'<<16:	return 1;
-			case 'Y'|'X'<<8|'Z'<<16:	return 2;
-			case 'Y'|'Z'<<8|'X'<<16:	return 3;
-			case 'Z'|'X'<<8|'Y'<<16:	return 4;
-			case 'Z'|'Y'<<8|'X'<<16:	return 5;
+			case 'X'|'Y'<<8|'Z'<<16:	return EULER_ORDER_XYZ;
+			case 'X'|'Z'<<8|'Y'<<16:	return EULER_ORDER_XZY;
+			case 'Y'|'X'<<8|'Z'<<16:	return EULER_ORDER_YXZ;
+			case 'Y'|'Z'<<8|'X'<<16:	return EULER_ORDER_YZX;
+			case 'Z'|'X'<<8|'Y'<<16:	return EULER_ORDER_ZXY;
+			case 'Z'|'Y'<<8|'X'<<16:	return EULER_ORDER_ZYX;
 		}
 	}
 
@@ -86,15 +88,15 @@
 	PyObject *ret;
 	int i;
 
-	ret= PyTuple_New(3);
+	ret= PyTuple_New(EULER_SIZE);
 
 	if(ndigits >= 0) {
-		for(i= 0; i < 3; i++) {
+		for(i= 0; i < EULER_SIZE; i++) {
 			PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->eul[i], ndigits)));
 		}
 	}
 	else {
-		for(i= 0; i < 3; i++) {
+		for(i= 0; i < EULER_SIZE; i++) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list