[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34433] trunk/blender/source/blender/ python/generic: change mathutils.Matrix.Shear() for 3x3 or 4x4 matrices

Campbell Barton ideasman42 at gmail.com
Fri Jan 21 04:18:02 CET 2011


Revision: 34433
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=34433
Author:   campbellbarton
Date:     2011-01-21 03:18:01 +0000 (Fri, 21 Jan 2011)
Log Message:
-----------
change mathutils.Matrix.Shear() for 3x3 or 4x4 matrices

The plane which defined the shear had the factor applied to each axis equally.
This meant that the shear for any 3x3 or 4x4 matrix would be diagonal on the positive values of each axis.
Only being able to create diagonal shear matrices seems stupid, now take a pair of floats for the shear factor corresponding to the plane axis values, so its possible to shear on only one axis of the plane. 

Modified Paths:
--------------
    trunk/blender/source/blender/python/generic/mathutils.c
    trunk/blender/source/blender/python/generic/mathutils_matrix.c

Modified: trunk/blender/source/blender/python/generic/mathutils.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils.c	2011-01-21 02:32:58 UTC (rev 34432)
+++ trunk/blender/source/blender/python/generic/mathutils.c	2011-01-21 03:18:01 UTC (rev 34433)
@@ -40,6 +40,7 @@
  * - Matrix.scalePart --> Matrix.scale_part
  * - Matrix.translationPart --> Matrix.translation_part
  * - Matrix.rotationPart --> Matrix.rotation_part
+ * - mathutils.Matrix.Shear(plane, fac, size), now takes a pair of floats for 3x3 or 4x4 shear factor.
  * - toMatrix --> to_matrix
  * - toEuler --> to_euler
  * - toQuat --> to_quat

Modified: trunk/blender/source/blender/python/generic/mathutils_matrix.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_matrix.c	2011-01-21 02:32:58 UTC (rev 34432)
+++ trunk/blender/source/blender/python/generic/mathutils_matrix.c	2011-01-21 03:18:01 UTC (rev 34433)
@@ -170,7 +170,7 @@
 	VectorObject *vec= NULL;
 	char *axis= NULL;
 	int matSize;
-	double angle; /* use double because of precission problems at high values */
+	double angle; /* use double because of precision problems at high values */
 	float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
 		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
 
@@ -330,8 +330,7 @@
 	float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
 		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
 
-	if(!PyArg_ParseTuple(args, "fi|O!", &factor, &matSize, &vector_Type, &vec)) {
-		PyErr_SetString(PyExc_TypeError, "mathutils.Matrix.Scale(): expected float int and optional vector");
+	if(!PyArg_ParseTuple(args, "fi|O!:Matrix.Scale", &factor, &matSize, &vector_Type, &vec)) {
 		return NULL;
 	}
 	if(matSize != 2 && matSize != 3 && matSize != 4) {
@@ -421,8 +420,7 @@
 	float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
 		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
 	
-	if(!PyArg_ParseTuple(args, "si|O!", &plane, &matSize, &vector_Type, &vec)) {
-		PyErr_SetString(PyExc_TypeError, "mathutils.Matrix.OrthoProjection(): expected string and int and optional vector");
+	if(!PyArg_ParseTuple(args, "si|O!:Matrix.OrthoProjection", &plane, &matSize, &vector_Type, &vec)) {
 		return NULL;
 	}
 	if(matSize != 2 && matSize != 3 && matSize != 4) {
@@ -506,25 +504,24 @@
 "\n"
 "   Create a matrix to represent an shear transformation.\n"
 "\n"
-"   :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'], where a single axis is for a 2D matrix.\n"
+"   :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'], where a single axis is for a 2D matrix only.\n"
 "   :type plane: string\n"
-"   :arg factor: The factor of shear to apply.\n"
-"   :type factor: float\n"
+"   :arg factor: The factor of shear to apply. For a 3 or 4 *size* matrix pass a pair of floats corrasponding with the *plane* axis.\n"
+"   :type factor: float or float pair\n"
 "   :arg size: The size of the shear matrix to construct [2, 4].\n"
 "   :type size: int\n"
 "   :return: A new shear matrix.\n"
-"   :rtype: :class:`Matrix`\n";
-
+"   :rtype: :class:`Matrix`\n"
+;
 static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
 {
 	int matSize;
 	char *plane;
-	float factor;
+	PyObject *fac;
 	float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
 		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
 
-	if(!PyArg_ParseTuple(args, "sfi", &plane, &factor, &matSize)) {
-		PyErr_SetString(PyExc_TypeError,"mathutils.Matrix.Shear(): expected string float and int");
+	if(!PyArg_ParseTuple(args, "sOi:Matrix.Shear", &plane, &fac, &matSize)) {
 		return NULL;
 	}
 	if(matSize != 2 && matSize != 3 && matSize != 4) {
@@ -532,37 +529,60 @@
 		return NULL;
 	}
 
-	if((strcmp(plane, "X") == 0)
-		&& matSize == 2) {
+	if(matSize == 2) {
+		float const factor= PyFloat_AsDouble(fac);
+
+		if(factor==-1.0 && PyErr_Occurred()) {
+			PyErr_SetString(PyExc_AttributeError, "mathutils.Matrix.Shear(): the factor to be a float");
+			return NULL;
+		}
+
+		/* unit */
 		mat[0] = 1.0f;
-		mat[2] = factor;
 		mat[3] = 1.0f;
-	} else if((strcmp(plane, "Y") == 0) && matSize == 2) {
+
+		if(strcmp(plane, "X") == 0) {
+			mat[2] = factor;
+		}
+		else if(strcmp(plane, "Y") == 0) {
+			mat[1] = factor;
+		}
+		else {
+			PyErr_SetString(PyExc_AttributeError, "Matrix.Shear(): expected: X, Y or wrong matrix size for shearing plane");
+			return NULL;
+		}
+	}
+	else {
+		/* 3 or 4, apply as 3x3, resize later if needed */
+		float factor[2];
+
+		if(mathutils_array_parse(factor, 2, 2, fac, "Matrix.Shear()") < 0) {
+			return NULL;
+		}
+
+		/* unit */
 		mat[0] = 1.0f;
-		mat[1] = factor;
-		mat[3] = 1.0f;
-	} else if((strcmp(plane, "XY") == 0) && matSize > 2) {
-		mat[0] = 1.0f;
 		mat[4] = 1.0f;
-		mat[6] = factor;
-		mat[7] = factor;
 		mat[8] = 1.0f;
-	} else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
-		mat[0] = 1.0f;
-		mat[3] = factor;
-		mat[4] = 1.0f;
-		mat[5] = factor;
-		mat[8] = 1.0f;
-	} else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
-		mat[0] = 1.0f;
-		mat[1] = factor;
-		mat[2] = factor;
-		mat[4] = 1.0f;
-		mat[8] = 1.0f;
-	} else {
-		PyErr_SetString(PyExc_AttributeError, "mathutils.Matrix.Shear(): expected: x, y, xy, xz, yz or wrong matrix size for shearing plane");
-		return NULL;
+
+		if(strcmp(plane, "XY") == 0) {
+			mat[6] = factor[0];
+			mat[7] = factor[1];
+		}
+		else if(strcmp(plane, "XZ") == 0) {
+			mat[3] = factor[0];
+			mat[5] = factor[1];
+		}
+		else if(strcmp(plane, "YZ") == 0) {
+			mat[1] = factor[0];
+			mat[2] = factor[1];
+		}
+		else {
+			PyErr_SetString(PyExc_AttributeError, "mathutils.Matrix.Shear(): expected: X, Y, XY, XZ, YZ");
+			return NULL;
+		}
 	}
+
 	if(matSize == 4) {
 		//resize matrix
 		mat[10] = mat[8];




More information about the Bf-blender-cvs mailing list