2009-06-17 20:33:34 +00:00
/*
*
* * * * * * BEGIN GPL LICENSE BLOCK * * * * *
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
2010-02-12 13:34:04 +00:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2009-06-17 20:33:34 +00:00
*
* The Original Code is Copyright ( C ) 2001 - 2002 by NaN Holding BV .
* All rights reserved .
*
* Contributor ( s ) : Michel Selten & Joseph Gilbert
*
* * * * * * END GPL LICENSE BLOCK * * * * *
*/
2011-11-05 01:48:10 +00:00
/** \file blender/python/mathutils/mathutils_Matrix.c
* \ ingroup pymathutils
2011-02-27 20:10:08 +00:00
*/
2011-02-14 04:15:25 +00:00
# include <Python.h>
2010-04-11 12:05:27 +00:00
# include "mathutils.h"
2009-06-17 20:33:34 +00:00
2009-11-10 20:43:45 +00:00
# include "BLI_math.h"
2011-01-07 18:36:47 +00:00
# include "BLI_utildefines.h"
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_copy ( MatrixObject * self ) ;
2011-02-04 03:06:23 +00:00
static int Matrix_ass_slice ( MatrixObject * self , int begin , int end , PyObject * value ) ;
2011-02-09 09:20:17 +00:00
static PyObject * matrix__apply_to_copy ( PyNoArgsFunction matrix_func , MatrixObject * self ) ;
2009-06-17 20:33:34 +00:00
2009-06-23 13:34:45 +00:00
/* matrix vector callbacks */
int mathutils_matrix_vector_cb_index = - 1 ;
2010-04-27 18:55:25 +00:00
static int mathutils_matrix_vector_check ( BaseMathObject * bmo )
2009-06-23 13:34:45 +00:00
{
2010-04-27 18:55:25 +00:00
MatrixObject * self = ( MatrixObject * ) bmo - > cb_user ;
2009-06-25 10:11:37 +00:00
return BaseMath_ReadCallback ( self ) ;
2009-06-23 13:34:45 +00:00
}
2010-04-27 19:21:36 +00:00
static int mathutils_matrix_vector_get ( BaseMathObject * bmo , int subtype )
2009-06-23 13:34:45 +00:00
{
2010-04-27 18:55:25 +00:00
MatrixObject * self = ( MatrixObject * ) bmo - > cb_user ;
2011-12-19 03:12:10 +00:00
int index ;
2009-08-15 16:36:25 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2011-02-28 18:42:41 +00:00
return - 1 ;
2009-06-23 13:34:45 +00:00
2011-12-19 03:12:10 +00:00
for ( index = 0 ; index < self - > col_size ; index + + ) {
bmo - > data [ index ] = MATRIX_ITEM ( self , subtype , index ) ;
}
2009-06-23 13:34:45 +00:00
2011-02-28 18:42:41 +00:00
return 0 ;
2009-06-23 13:34:45 +00:00
}
2010-04-27 19:21:36 +00:00
static int mathutils_matrix_vector_set ( BaseMathObject * bmo , int subtype )
2009-06-23 13:34:45 +00:00
{
2010-04-27 18:55:25 +00:00
MatrixObject * self = ( MatrixObject * ) bmo - > cb_user ;
2011-12-19 03:12:10 +00:00
int index ;
2009-08-15 16:36:25 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2011-02-28 18:42:41 +00:00
return - 1 ;
2009-06-23 13:34:45 +00:00
2011-12-19 03:12:10 +00:00
for ( index = 0 ; index < self - > col_size ; index + + ) {
MATRIX_ITEM ( self , subtype , index ) = bmo - > data [ index ] ;
}
2009-06-23 13:34:45 +00:00
2010-10-20 12:11:09 +00:00
( void ) BaseMath_WriteCallback ( self ) ;
2011-02-28 18:42:41 +00:00
return 0 ;
2009-06-23 13:34:45 +00:00
}
2010-04-27 19:21:36 +00:00
static int mathutils_matrix_vector_get_index ( BaseMathObject * bmo , int subtype , int index )
2009-06-23 13:34:45 +00:00
{
2010-04-27 18:55:25 +00:00
MatrixObject * self = ( MatrixObject * ) bmo - > cb_user ;
2009-08-15 16:36:25 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2011-02-28 18:42:41 +00:00
return - 1 ;
2009-06-23 13:34:45 +00:00
2011-12-19 03:12:10 +00:00
bmo - > data [ index ] = MATRIX_ITEM ( self , subtype , index ) ;
2011-02-28 18:42:41 +00:00
return 0 ;
2009-06-23 13:34:45 +00:00
}
2010-04-27 19:21:36 +00:00
static int mathutils_matrix_vector_set_index ( BaseMathObject * bmo , int subtype , int index )
2009-06-23 13:34:45 +00:00
{
2010-04-27 18:55:25 +00:00
MatrixObject * self = ( MatrixObject * ) bmo - > cb_user ;
2009-08-15 16:36:25 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2011-02-28 18:42:41 +00:00
return - 1 ;
2009-06-23 13:34:45 +00:00
2011-12-19 03:12:10 +00:00
MATRIX_ITEM ( self , subtype , index ) = bmo - > data [ index ] ;
2009-06-23 13:34:45 +00:00
2010-10-20 12:11:09 +00:00
( void ) BaseMath_WriteCallback ( self ) ;
2011-02-28 18:42:41 +00:00
return 0 ;
2009-06-23 13:34:45 +00:00
}
Mathutils_Callback mathutils_matrix_vector_cb = {
mathutils_matrix_vector_check ,
mathutils_matrix_vector_get ,
mathutils_matrix_vector_set ,
mathutils_matrix_vector_get_index ,
mathutils_matrix_vector_set_index
} ;
/* matrix vector callbacks, this is so you can do matrix[i][j] = val */
2010-04-11 14:22:27 +00:00
//----------------------------------mathutils.Matrix() -----------------
2011-03-19 11:12:48 +00:00
//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc.
2009-06-20 02:44:57 +00:00
//create a new matrix type
2010-11-28 06:03:30 +00:00
static PyObject * Matrix_new ( PyTypeObject * type , PyObject * args , PyObject * kwds )
2009-06-20 02:44:57 +00:00
{
2011-10-13 01:29:08 +00:00
if ( kwds & & PyDict_Size ( kwds ) ) {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix(): "
2011-07-14 01:25:05 +00:00
" takes no keyword args " ) ;
2010-10-13 23:25:08 +00:00
return NULL ;
}
2011-12-18 08:50:06 +00:00
switch ( PyTuple_GET_SIZE ( args ) ) {
2011-01-09 14:30:16 +00:00
case 0 :
2011-11-29 20:22:35 +00:00
return Matrix_CreatePyObject ( NULL , 4 , 4 , Py_NEW , type ) ;
2011-01-09 14:30:16 +00:00
case 1 :
{
PyObject * arg = PyTuple_GET_ITEM ( args , 0 ) ;
2009-06-20 02:44:57 +00:00
2011-07-14 01:25:05 +00:00
/* -1 is an error, size checks will accunt for this */
const unsigned short row_size = PySequence_Size ( arg ) ;
2009-06-20 02:44:57 +00:00
2011-10-13 01:29:08 +00:00
if ( row_size > = 2 & & row_size < = 4 ) {
2011-01-09 14:30:16 +00:00
PyObject * item = PySequence_GetItem ( arg , 0 ) ;
const unsigned short col_size = PySequence_Size ( item ) ;
Py_XDECREF ( item ) ;
2009-06-20 02:44:57 +00:00
2011-10-13 01:29:08 +00:00
if ( col_size > = 2 & & col_size < = 4 ) {
2011-01-09 14:30:16 +00:00
/* sane row & col size, new matrix and assign as slice */
2011-11-24 04:45:36 +00:00
PyObject * matrix = Matrix_CreatePyObject ( NULL , row_size , col_size , Py_NEW , type ) ;
2011-10-13 01:29:08 +00:00
if ( Matrix_ass_slice ( ( MatrixObject * ) matrix , 0 , INT_MAX , arg ) = = 0 ) {
2011-01-09 14:30:16 +00:00
return matrix ;
}
else { /* matrix ok, slice assignment not */
Py_DECREF ( matrix ) ;
}
}
2009-06-20 02:44:57 +00:00
}
}
}
2011-01-09 14:30:16 +00:00
/* will overwrite error */
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix(): "
2011-07-14 01:25:05 +00:00
" expects no args or 2-4 numeric sequences " ) ;
2011-01-09 14:30:16 +00:00
return NULL ;
2009-06-20 02:44:57 +00:00
}
2011-02-09 09:20:17 +00:00
static PyObject * matrix__apply_to_copy ( PyNoArgsFunction matrix_func , MatrixObject * self )
{
PyObject * ret = Matrix_copy ( self ) ;
PyObject * ret_dummy = matrix_func ( ret ) ;
2011-10-13 01:29:08 +00:00
if ( ret_dummy ) {
2011-02-09 09:20:17 +00:00
Py_DECREF ( ret_dummy ) ;
return ( PyObject * ) ret ;
}
else { /* error */
Py_DECREF ( ret ) ;
return NULL ;
}
}
2011-02-06 11:17:22 +00:00
/* when a matrix is 4x4 size but initialized as a 3x3, re-assign values for 4x4 */
static void matrix_3x3_as_4x4 ( float mat [ 16 ] )
{
mat [ 10 ] = mat [ 8 ] ;
mat [ 9 ] = mat [ 7 ] ;
mat [ 8 ] = mat [ 6 ] ;
mat [ 7 ] = 0.0f ;
mat [ 6 ] = mat [ 5 ] ;
mat [ 5 ] = mat [ 4 ] ;
mat [ 4 ] = mat [ 3 ] ;
mat [ 3 ] = 0.0f ;
}
2010-08-11 16:40:36 +00:00
/*-----------------------CLASS-METHODS----------------------------*/
2011-03-19 11:12:48 +00:00
//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc.
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( C_Matrix_Rotation_doc ,
2010-08-11 16:40:36 +00:00
" .. classmethod:: Rotation(angle, size, axis) \n "
" \n "
" Create a matrix representing a rotation. \n "
" \n "
" :arg angle: The angle of rotation desired, in radians. \n "
" :type angle: float \n "
" :arg size: The size of the rotation matrix to construct [2, 4]. \n "
" :type size: int \n "
2011-05-26 19:13:01 +00:00
" :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object \n "
" (optional when size is 2). \n "
2010-08-11 16:40:36 +00:00
" :type axis: string or :class:`Vector` \n "
" :return: A new rotation matrix. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2010-08-11 16:40:36 +00:00
static PyObject * C_Matrix_Rotation ( PyObject * cls , PyObject * args )
{
2011-02-04 03:06:23 +00:00
PyObject * vec = NULL ;
const char * axis = NULL ;
2010-08-11 16:40:36 +00:00
int matSize ;
2011-01-21 03:18:01 +00:00
double angle ; /* use double because of precision problems at high values */
2010-08-11 16:40:36 +00:00
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 } ;
2011-10-13 01:29:08 +00:00
if ( ! PyArg_ParseTuple ( args , " di|O " , & angle , & matSize , & vec ) ) {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.Rotation(angle, size, axis): "
2011-07-14 01:25:05 +00:00
" expected float int and a string or vector " ) ;
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( vec & & PyUnicode_Check ( vec ) ) {
2010-08-11 16:40:36 +00:00
axis = _PyUnicode_AsString ( ( PyObject * ) vec ) ;
2011-10-13 01:29:08 +00:00
if ( axis = = NULL | | axis [ 0 ] = = ' \0 ' | | axis [ 1 ] ! = ' \0 ' | | axis [ 0 ] < ' X ' | | axis [ 0 ] > ' Z ' ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.Rotation(): "
2011-07-14 01:25:05 +00:00
" 3rd argument axis value must be a 3D vector "
" or a string in 'X', 'Y', 'Z' " ) ;
2010-08-11 16:40:36 +00:00
return NULL ;
}
else {
/* use the string */
vec = NULL ;
}
}
2011-04-02 03:05:49 +00:00
angle = angle_wrap_rad ( angle ) ;
2011-01-11 09:41:26 +00:00
2011-10-13 01:29:08 +00:00
if ( matSize ! = 2 & & matSize ! = 3 & & matSize ! = 4 ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.Rotation(): "
2011-07-14 01:25:05 +00:00
" can only return a 2x2 3x3 or 4x4 matrix " ) ;
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( matSize = = 2 & & ( vec ! = NULL ) ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.Rotation(): "
2011-07-14 01:25:05 +00:00
" cannot create a 2x2 rotation matrix around arbitrary axis " ) ;
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( ( matSize = = 3 | | matSize = = 4 ) & & ( axis = = NULL ) & & ( vec = = NULL ) ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.Rotation(): "
2011-07-14 01:25:05 +00:00
" axis of rotation for 3d and 4d matrices is required " ) ;
2010-08-11 16:40:36 +00:00
return NULL ;
}
/* check for valid vector/axis above */
2011-10-13 01:29:08 +00:00
if ( vec ) {
2011-02-04 03:06:23 +00:00
float tvec [ 3 ] ;
2011-09-19 14:29:21 +00:00
if ( mathutils_array_parse ( tvec , 3 , 3 , vec , " Matrix.Rotation(angle, size, axis), invalid 'axis' arg " ) = = - 1 )
2011-02-04 03:06:23 +00:00
return NULL ;
axis_angle_to_mat3 ( ( float ( * ) [ 3 ] ) mat , tvec , angle ) ;
2010-08-11 16:40:36 +00:00
}
2011-09-19 13:08:01 +00:00
else if ( matSize = = 2 ) {
const float angle_cos = cosf ( angle ) ;
const float angle_sin = sinf ( angle ) ;
2010-08-11 16:40:36 +00:00
//2D rotation matrix
2011-09-19 13:08:01 +00:00
mat [ 0 ] = angle_cos ;
mat [ 1 ] = angle_sin ;
mat [ 2 ] = - angle_sin ;
mat [ 3 ] = angle_cos ;
2010-08-11 16:40:36 +00:00
}
else {
2011-09-19 13:08:01 +00:00
/* valid axis checked above */
single_axis_angle_to_mat3 ( ( float ( * ) [ 3 ] ) mat , axis [ 0 ] , angle ) ;
2010-08-11 16:40:36 +00:00
}
2011-10-13 01:29:08 +00:00
if ( matSize = = 4 ) {
2011-02-06 11:17:22 +00:00
matrix_3x3_as_4x4 ( mat ) ;
2010-08-11 16:40:36 +00:00
}
//pass to matrix creation
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( mat , matSize , matSize , Py_NEW , ( PyTypeObject * ) cls ) ;
2010-08-11 16:40:36 +00:00
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( C_Matrix_Translation_doc ,
2010-08-11 16:40:36 +00:00
" .. classmethod:: Translation(vector) \n "
" \n "
" Create a matrix representing a translation. \n "
" \n "
" :arg vector: The translation vector. \n "
" :type vector: :class:`Vector` \n "
" :return: An identity matrix with a translation. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-04 03:06:23 +00:00
static PyObject * C_Matrix_Translation ( PyObject * cls , PyObject * value )
2010-08-11 16:40:36 +00:00
{
2011-02-04 03:06:23 +00:00
float mat [ 16 ] , tvec [ 3 ] ;
if ( mathutils_array_parse ( tvec , 3 , 4 , value , " mathutils.Matrix.Translation(vector), invalid vector arg " ) = = - 1 )
2010-08-11 16:40:36 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
/* create a identity matrix and add translation */
unit_m4 ( ( float ( * ) [ 4 ] ) mat ) ;
copy_v3_v3 ( mat + 12 , tvec ) ; /* 12, 13, 14 */
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( mat , 4 , 4 , Py_NEW , ( PyTypeObject * ) cls ) ;
2010-08-11 16:40:36 +00:00
}
2010-11-21 09:06:27 +00:00
//----------------------------------mathutils.Matrix.Scale() -------------
2011-03-19 11:12:48 +00:00
//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc.
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( C_Matrix_Scale_doc ,
2010-08-11 16:40:36 +00:00
" .. classmethod:: Scale(factor, size, axis) \n "
" \n "
" Create a matrix representing a scaling. \n "
" \n "
" :arg factor: The factor of scaling to apply. \n "
" :type factor: float \n "
" :arg size: The size of the scale matrix to construct [2, 4]. \n "
" :type size: int \n "
" :arg axis: Direction to influence scale. (optional). \n "
" :type axis: :class:`Vector` \n "
" :return: A new scale matrix. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2010-08-11 16:40:36 +00:00
static PyObject * C_Matrix_Scale ( PyObject * cls , PyObject * args )
{
2011-02-06 11:17:22 +00:00
PyObject * vec = NULL ;
int vec_size ;
float tvec [ 3 ] ;
float factor ;
int matSize ;
2010-08-11 16:40:36 +00:00
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 } ;
2011-10-13 01:29:08 +00:00
if ( ! PyArg_ParseTuple ( args , " fi|O:Matrix.Scale " , & factor , & matSize , & vec ) ) {
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( matSize ! = 2 & & matSize ! = 3 & & matSize ! = 4 ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-07-14 01:25:05 +00:00
" Matrix.Scale(): "
" can only return a 2x2 3x3 or 4x4 matrix " ) ;
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( vec ) {
2011-02-06 11:17:22 +00:00
vec_size = ( matSize = = 2 ? 2 : 3 ) ;
2011-10-13 01:29:08 +00:00
if ( mathutils_array_parse ( tvec , vec_size , vec_size , vec , " Matrix.Scale(factor, size, axis), invalid 'axis' arg " ) = = - 1 ) {
2010-08-11 16:40:36 +00:00
return NULL ;
}
}
2011-10-13 01:29:08 +00:00
if ( vec = = NULL ) { //scaling along axis
if ( matSize = = 2 ) {
2010-08-11 16:40:36 +00:00
mat [ 0 ] = factor ;
mat [ 3 ] = factor ;
2011-07-14 01:25:05 +00:00
}
else {
2010-08-11 16:40:36 +00:00
mat [ 0 ] = factor ;
mat [ 4 ] = factor ;
mat [ 8 ] = factor ;
}
2011-02-06 11:17:22 +00:00
}
else { //scaling in arbitrary direction
2010-08-11 16:40:36 +00:00
//normalize arbitrary axis
2011-02-06 11:17:22 +00:00
float norm = 0.0f ;
int x ;
2011-10-13 01:29:08 +00:00
for ( x = 0 ; x < vec_size ; x + + ) {
2011-02-06 11:17:22 +00:00
norm + = tvec [ x ] * tvec [ x ] ;
2010-08-11 16:40:36 +00:00
}
norm = ( float ) sqrt ( norm ) ;
2011-10-13 01:29:08 +00:00
for ( x = 0 ; x < vec_size ; x + + ) {
2011-02-06 11:17:22 +00:00
tvec [ x ] / = norm ;
2010-08-11 16:40:36 +00:00
}
2011-10-13 01:29:08 +00:00
if ( matSize = = 2 ) {
2011-02-06 11:17:22 +00:00
mat [ 0 ] = 1 + ( ( factor - 1 ) * ( tvec [ 0 ] * tvec [ 0 ] ) ) ;
mat [ 1 ] = ( ( factor - 1 ) * ( tvec [ 0 ] * tvec [ 1 ] ) ) ;
mat [ 2 ] = ( ( factor - 1 ) * ( tvec [ 0 ] * tvec [ 1 ] ) ) ;
mat [ 3 ] = 1 + ( ( factor - 1 ) * ( tvec [ 1 ] * tvec [ 1 ] ) ) ;
2011-07-14 01:25:05 +00:00
}
else {
2011-02-06 11:17:22 +00:00
mat [ 0 ] = 1 + ( ( factor - 1 ) * ( tvec [ 0 ] * tvec [ 0 ] ) ) ;
mat [ 1 ] = ( ( factor - 1 ) * ( tvec [ 0 ] * tvec [ 1 ] ) ) ;
mat [ 2 ] = ( ( factor - 1 ) * ( tvec [ 0 ] * tvec [ 2 ] ) ) ;
mat [ 3 ] = ( ( factor - 1 ) * ( tvec [ 0 ] * tvec [ 1 ] ) ) ;
mat [ 4 ] = 1 + ( ( factor - 1 ) * ( tvec [ 1 ] * tvec [ 1 ] ) ) ;
mat [ 5 ] = ( ( factor - 1 ) * ( tvec [ 1 ] * tvec [ 2 ] ) ) ;
mat [ 6 ] = ( ( factor - 1 ) * ( tvec [ 0 ] * tvec [ 2 ] ) ) ;
mat [ 7 ] = ( ( factor - 1 ) * ( tvec [ 1 ] * tvec [ 2 ] ) ) ;
mat [ 8 ] = 1 + ( ( factor - 1 ) * ( tvec [ 2 ] * tvec [ 2 ] ) ) ;
2010-08-11 16:40:36 +00:00
}
}
2011-10-13 01:29:08 +00:00
if ( matSize = = 4 ) {
2011-02-06 11:17:22 +00:00
matrix_3x3_as_4x4 ( mat ) ;
2010-08-11 16:40:36 +00:00
}
//pass to matrix creation
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( mat , matSize , matSize , Py_NEW , ( PyTypeObject * ) cls ) ;
2010-08-11 16:40:36 +00:00
}
2010-11-21 09:06:27 +00:00
//----------------------------------mathutils.Matrix.OrthoProjection() ---
2011-03-19 11:12:48 +00:00
//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc.
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( C_Matrix_OrthoProjection_doc ,
2011-02-04 09:35:20 +00:00
" .. classmethod:: OrthoProjection(axis, size) \n "
2010-08-11 16:40:36 +00:00
" \n "
" Create a matrix to represent an orthographic projection. \n "
" \n "
2011-05-26 19:13:01 +00:00
" :arg axis: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'], \n "
" where a single axis is for a 2D matrix. \n "
" Or a vector for an arbitrary axis \n "
2011-02-04 09:35:20 +00:00
" :type axis: string or :class:`Vector` \n "
2010-08-11 16:40:36 +00:00
" :arg size: The size of the projection matrix to construct [2, 4]. \n "
" :type size: int \n "
" :return: A new projection matrix. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2010-08-11 16:40:36 +00:00
static PyObject * C_Matrix_OrthoProjection ( PyObject * cls , PyObject * args )
{
2011-02-04 09:35:20 +00:00
PyObject * axis ;
2010-08-11 16:40:36 +00:00
int matSize , x ;
float norm = 0.0f ;
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 } ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( ! PyArg_ParseTuple ( args , " Oi:Matrix.OrthoProjection " , & axis , & matSize ) ) {
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( matSize ! = 2 & & matSize ! = 3 & & matSize ! = 4 ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.OrthoProjection(): "
2011-07-14 01:25:05 +00:00
" can only return a 2x2 3x3 or 4x4 matrix " ) ;
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-02-04 09:35:20 +00:00
2011-10-13 01:29:08 +00:00
if ( PyUnicode_Check ( axis ) ) { //ortho projection onto cardinal plane
2011-02-04 09:35:20 +00:00
Py_ssize_t plane_len ;
const char * plane = _PyUnicode_AsStringAndSize ( axis , & plane_len ) ;
2011-10-13 01:29:08 +00:00
if ( matSize = = 2 ) {
if ( plane_len = = 1 & & plane [ 0 ] = = ' X ' ) {
2011-02-04 09:35:20 +00:00
mat [ 0 ] = 1.0f ;
}
else if ( plane_len = = 1 & & plane [ 0 ] = = ' Y ' ) {
mat [ 3 ] = 1.0f ;
}
else {
2011-07-14 01:25:05 +00:00
PyErr_Format ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.OrthoProjection(): "
2011-07-14 01:25:05 +00:00
" unknown plane, expected: X, Y, not '%.200s' " ,
plane ) ;
2011-02-04 09:35:20 +00:00
return NULL ;
}
}
else {
2011-10-13 01:29:08 +00:00
if ( plane_len = = 2 & & plane [ 0 ] = = ' X ' & & plane [ 1 ] = = ' Y ' ) {
2011-02-04 09:35:20 +00:00
mat [ 0 ] = 1.0f ;
mat [ 4 ] = 1.0f ;
}
else if ( plane_len = = 2 & & plane [ 0 ] = = ' X ' & & plane [ 1 ] = = ' Z ' ) {
mat [ 0 ] = 1.0f ;
mat [ 8 ] = 1.0f ;
}
else if ( plane_len = = 2 & & plane [ 0 ] = = ' Y ' & & plane [ 1 ] = = ' Z ' ) {
mat [ 4 ] = 1.0f ;
mat [ 8 ] = 1.0f ;
}
else {
2011-07-14 01:25:05 +00:00
PyErr_Format ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.OrthoProjection(): "
2011-07-14 01:25:05 +00:00
" unknown plane, expected: XY, XZ, YZ, not '%.200s' " ,
plane ) ;
2011-02-04 09:35:20 +00:00
return NULL ;
}
2010-08-11 16:40:36 +00:00
}
2011-02-04 03:06:23 +00:00
}
else {
//arbitrary plane
2011-02-04 09:35:20 +00:00
int vec_size = ( matSize = = 2 ? 2 : 3 ) ;
2011-02-04 03:06:23 +00:00
float tvec [ 4 ] ;
2011-11-29 20:22:35 +00:00
if ( mathutils_array_parse ( tvec , vec_size , vec_size , axis ,
" Matrix.OrthoProjection(axis, size), invalid 'axis' arg " ) = = - 1 )
{
2011-02-04 03:06:23 +00:00
return NULL ;
}
2010-08-11 16:40:36 +00:00
//normalize arbitrary axis
2011-10-13 01:29:08 +00:00
for ( x = 0 ; x < vec_size ; x + + ) {
2011-02-04 03:06:23 +00:00
norm + = tvec [ x ] * tvec [ x ] ;
2010-08-11 16:40:36 +00:00
}
norm = ( float ) sqrt ( norm ) ;
2011-10-13 01:29:08 +00:00
for ( x = 0 ; x < vec_size ; x + + ) {
2011-02-04 03:06:23 +00:00
tvec [ x ] / = norm ;
2010-08-11 16:40:36 +00:00
}
2011-10-13 01:29:08 +00:00
if ( matSize = = 2 ) {
2011-02-04 03:06:23 +00:00
mat [ 0 ] = 1 - ( tvec [ 0 ] * tvec [ 0 ] ) ;
mat [ 1 ] = - ( tvec [ 0 ] * tvec [ 1 ] ) ;
mat [ 2 ] = - ( tvec [ 0 ] * tvec [ 1 ] ) ;
mat [ 3 ] = 1 - ( tvec [ 1 ] * tvec [ 1 ] ) ;
2011-02-04 09:35:20 +00:00
}
2011-10-13 01:29:08 +00:00
else if ( matSize > 2 ) {
2011-02-04 03:06:23 +00:00
mat [ 0 ] = 1 - ( tvec [ 0 ] * tvec [ 0 ] ) ;
mat [ 1 ] = - ( tvec [ 0 ] * tvec [ 1 ] ) ;
mat [ 2 ] = - ( tvec [ 0 ] * tvec [ 2 ] ) ;
mat [ 3 ] = - ( tvec [ 0 ] * tvec [ 1 ] ) ;
mat [ 4 ] = 1 - ( tvec [ 1 ] * tvec [ 1 ] ) ;
mat [ 5 ] = - ( tvec [ 1 ] * tvec [ 2 ] ) ;
mat [ 6 ] = - ( tvec [ 0 ] * tvec [ 2 ] ) ;
mat [ 7 ] = - ( tvec [ 1 ] * tvec [ 2 ] ) ;
mat [ 8 ] = 1 - ( tvec [ 2 ] * tvec [ 2 ] ) ;
2010-08-11 16:40:36 +00:00
}
}
2011-10-13 01:29:08 +00:00
if ( matSize = = 4 ) {
2011-02-06 11:17:22 +00:00
matrix_3x3_as_4x4 ( mat ) ;
2010-08-11 16:40:36 +00:00
}
//pass to matrix creation
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( mat , matSize , matSize , Py_NEW , ( PyTypeObject * ) cls ) ;
2010-08-11 16:40:36 +00:00
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( C_Matrix_Shear_doc ,
2011-02-04 09:41:59 +00:00
" .. classmethod:: Shear(plane, size, factor) \n "
2010-08-11 16:40:36 +00:00
" \n "
" Create a matrix to represent an shear transformation. \n "
" \n "
2011-05-26 19:13:01 +00:00
" :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'], \n "
" where a single axis is for a 2D matrix only. \n "
2010-08-11 16:40:36 +00:00
" :type plane: string \n "
" :arg size: The size of the shear matrix to construct [2, 4]. \n "
" :type size: int \n "
2011-05-26 19:13:01 +00:00
" :arg factor: The factor of shear to apply. For a 3 or 4 *size* matrix \n "
" pass a pair of floats corrasponding with the *plane* axis. \n "
2011-02-04 09:41:59 +00:00
" :type factor: float or float pair \n "
2010-08-11 16:40:36 +00:00
" :return: A new shear matrix. \n "
2011-01-21 03:18:01 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2010-08-11 16:40:36 +00:00
static PyObject * C_Matrix_Shear ( PyObject * cls , PyObject * args )
{
int matSize ;
2011-02-04 03:06:23 +00:00
const char * plane ;
2011-01-21 03:18:01 +00:00
PyObject * fac ;
2010-08-11 16:40:36 +00:00
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 } ;
2011-10-13 01:29:08 +00:00
if ( ! PyArg_ParseTuple ( args , " siO:Matrix.Shear " , & plane , & matSize , & fac ) ) {
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( matSize ! = 2 & & matSize ! = 3 & & matSize ! = 4 ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.Shear(): "
2011-07-14 01:25:05 +00:00
" can only return a 2x2 3x3 or 4x4 matrix " ) ;
2010-08-11 16:40:36 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( matSize = = 2 ) {
2011-01-21 03:18:01 +00:00
float const factor = PyFloat_AsDouble ( fac ) ;
2011-10-13 01:29:08 +00:00
if ( factor = = - 1.0f & & PyErr_Occurred ( ) ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.Shear(): "
2011-07-14 01:25:05 +00:00
" the factor to be a float " ) ;
2011-01-21 03:18:01 +00:00
return NULL ;
}
/* unit */
2010-08-11 16:40:36 +00:00
mat [ 0 ] = 1.0f ;
mat [ 3 ] = 1.0f ;
2011-01-21 03:18:01 +00:00
2011-10-13 01:29:08 +00:00
if ( strcmp ( plane , " X " ) = = 0 ) {
2011-01-21 03:18:01 +00:00
mat [ 2 ] = factor ;
}
2011-10-13 01:29:08 +00:00
else if ( strcmp ( plane , " Y " ) = = 0 ) {
2011-01-21 03:18:01 +00:00
mat [ 1 ] = factor ;
}
else {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-07-14 01:25:05 +00:00
" Matrix.Shear(): "
" expected: X, Y or wrong matrix size for shearing plane " ) ;
2011-01-21 03:18:01 +00:00
return NULL ;
}
}
else {
/* 3 or 4, apply as 3x3, resize later if needed */
float factor [ 2 ] ;
2011-10-13 01:29:08 +00:00
if ( mathutils_array_parse ( factor , 2 , 2 , fac , " Matrix.Shear() " ) < 0 ) {
2011-01-21 03:18:01 +00:00
return NULL ;
}
/* unit */
2010-08-11 16:40:36 +00:00
mat [ 0 ] = 1.0f ;
mat [ 4 ] = 1.0f ;
mat [ 8 ] = 1.0f ;
2011-01-21 03:18:01 +00:00
2011-10-13 01:29:08 +00:00
if ( strcmp ( plane , " XY " ) = = 0 ) {
2011-01-21 03:18:01 +00:00
mat [ 6 ] = factor [ 0 ] ;
mat [ 7 ] = factor [ 1 ] ;
}
2011-10-13 01:29:08 +00:00
else if ( strcmp ( plane , " XZ " ) = = 0 ) {
2011-01-21 03:18:01 +00:00
mat [ 3 ] = factor [ 0 ] ;
mat [ 5 ] = factor [ 1 ] ;
}
2011-10-13 01:29:08 +00:00
else if ( strcmp ( plane , " YZ " ) = = 0 ) {
2011-01-21 03:18:01 +00:00
mat [ 1 ] = factor [ 0 ] ;
mat [ 2 ] = factor [ 1 ] ;
}
else {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.Shear(): "
2011-07-14 01:25:05 +00:00
" expected: X, Y, XY, XZ, YZ " ) ;
2011-01-21 03:18:01 +00:00
return NULL ;
}
2010-08-11 16:40:36 +00:00
}
2011-01-21 03:18:01 +00:00
2011-10-13 01:29:08 +00:00
if ( matSize = = 4 ) {
2011-02-06 11:17:22 +00:00
matrix_3x3_as_4x4 ( mat ) ;
2010-08-11 16:40:36 +00:00
}
//pass to matrix creation
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( mat , matSize , matSize , Py_NEW , ( PyTypeObject * ) cls ) ;
2010-08-11 16:40:36 +00:00
}
2011-02-05 09:57:02 +00:00
void matrix_as_3x3 ( float mat [ 3 ] [ 3 ] , MatrixObject * self )
2011-01-25 16:32:41 +00:00
{
2011-12-19 03:12:10 +00:00
copy_v3_v3 ( mat [ 0 ] , MATRIX_ROW_PTR ( self , 0 ) ) ;
copy_v3_v3 ( mat [ 1 ] , MATRIX_ROW_PTR ( self , 1 ) ) ;
copy_v3_v3 ( mat [ 2 ] , MATRIX_ROW_PTR ( self , 2 ) ) ;
2011-01-25 16:32:41 +00:00
}
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
/* assumes rowsize == colsize is checked and the read callback has run */
2011-02-04 03:06:23 +00:00
static float matrix_determinant_internal ( MatrixObject * self )
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
{
2011-10-13 01:29:08 +00:00
if ( self - > row_size = = 2 ) {
2011-12-19 03:12:10 +00:00
return determinant_m2 ( MATRIX_ITEM ( self , 0 , 0 ) , MATRIX_ITEM ( self , 0 , 1 ) ,
MATRIX_ITEM ( self , 1 , 0 ) , MATRIX_ITEM ( self , 1 , 1 ) ) ;
2011-03-19 11:12:48 +00:00
}
2011-10-13 01:29:08 +00:00
else if ( self - > row_size = = 3 ) {
2011-12-19 03:12:10 +00:00
return determinant_m3 ( MATRIX_ITEM ( self , 0 , 0 ) , MATRIX_ITEM ( self , 0 , 1 ) , MATRIX_ITEM ( self , 0 , 2 ) ,
MATRIX_ITEM ( self , 1 , 0 ) , MATRIX_ITEM ( self , 1 , 1 ) , MATRIX_ITEM ( self , 1 , 2 ) ,
MATRIX_ITEM ( self , 2 , 0 ) , MATRIX_ITEM ( self , 2 , 1 ) , MATRIX_ITEM ( self , 2 , 2 ) ) ;
2011-07-14 01:25:05 +00:00
}
else {
2010-02-23 09:39:47 +00:00
return determinant_m4 ( ( float ( * ) [ 4 ] ) self - > contigPtr ) ;
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
}
}
2009-06-17 20:33:34 +00:00
/*-----------------------------METHODS----------------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_to_quaternion_doc ,
2011-02-06 10:18:20 +00:00
" .. method:: to_quaternion() \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" \n "
" Return a quaternion representation of the rotation matrix. \n "
" \n "
" :return: Quaternion representation of the rotation matrix. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Quaternion` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-04 03:06:23 +00:00
static PyObject * Matrix_to_quaternion ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
float quat [ 4 ] ;
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2009-06-17 20:33:34 +00:00
/*must be 3-4 cols, 3-4 rows, square matrix*/
2011-10-13 01:29:08 +00:00
if ( ( self - > col_size < 3 ) | | ( self - > row_size < 3 ) | | ( self - > col_size ! = self - > row_size ) ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.to_quat(): "
2011-07-14 01:25:05 +00:00
" inappropriate matrix size - expects 3x3 or 4x4 matrix " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
}
2011-10-13 01:29:08 +00:00
if ( self - > col_size = = 3 ) {
2011-03-19 11:12:48 +00:00
mat3_to_quat ( quat , ( float ( * ) [ 3 ] ) self - > contigPtr ) ;
}
else {
mat4_to_quat ( quat , ( float ( * ) [ 4 ] ) self - > contigPtr ) ;
2009-06-17 20:33:34 +00:00
}
2011-02-04 03:06:23 +00:00
2011-11-24 04:45:36 +00:00
return Quaternion_CreatePyObject ( quat , Py_NEW , NULL ) ;
2009-06-17 20:33:34 +00:00
}
2010-02-20 19:49:04 +00:00
2011-07-14 01:25:05 +00:00
/*---------------------------matrix.toEuler() --------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_to_euler_doc ,
2010-02-20 19:49:04 +00:00
" .. method:: to_euler(order, euler_compat) \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" \n "
2011-05-26 19:13:01 +00:00
" Return an Euler representation of the rotation matrix \n "
" (3x3 or 4x4 matrix only). \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" \n "
2011-05-26 19:13:01 +00:00
" :arg order: Optional rotation order argument in \n "
" ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']. \n "
2010-02-20 19:49:04 +00:00
" :type order: string \n "
2011-05-26 19:13:01 +00:00
" :arg euler_compat: Optional euler argument the new euler will be made \n "
" compatible with (no axis flipping between them). \n "
" Useful for converting a series of matrices to animation curves. \n "
2010-01-27 21:33:39 +00:00
" :type euler_compat: :class:`Euler` \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" :return: Euler representation of the matrix. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Euler` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_to_euler ( MatrixObject * self , PyObject * args )
2009-06-17 20:33:34 +00:00
{
2011-02-04 03:06:23 +00:00
const char * order_str = NULL ;
2010-04-25 23:33:09 +00:00
short order = EULER_ORDER_XYZ ;
2009-06-17 20:33:34 +00:00
float eul [ 3 ] , eul_compatf [ 3 ] ;
EulerObject * eul_compat = NULL ;
2010-02-20 19:49:04 +00:00
float tmat [ 3 ] [ 3 ] ;
float ( * mat ) [ 3 ] ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( ! PyArg_ParseTuple ( args , " |sO!:to_euler " , & order_str , & euler_Type , & eul_compat ) )
2009-06-17 20:33:34 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( eul_compat ) {
if ( BaseMath_ReadCallback ( eul_compat ) = = - 1 )
2009-06-25 10:11:37 +00:00
return NULL ;
2009-06-25 20:47:41 +00:00
2010-04-25 23:33:09 +00:00
copy_v3_v3 ( eul_compatf , eul_compat - > eul ) ;
2009-06-17 20:33:34 +00:00
}
2011-02-04 03:06:23 +00:00
2009-06-17 20:33:34 +00:00
/*must be 3-4 cols, 3-4 rows, square matrix*/
2011-10-13 01:29:08 +00:00
if ( self - > col_size = = 3 & & self - > row_size = = 3 ) {
2010-02-23 09:39:47 +00:00
mat = ( float ( * ) [ 3 ] ) self - > contigPtr ;
2011-03-19 11:12:48 +00:00
}
else if ( self - > col_size = = 4 & & self - > row_size = = 4 ) {
2010-02-23 09:39:47 +00:00
copy_m3_m4 ( tmat , ( float ( * ) [ 4 ] ) self - > contigPtr ) ;
2010-02-20 19:49:04 +00:00
mat = tmat ;
2011-03-19 11:12:48 +00:00
}
else {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.to_euler(): "
2011-07-14 01:25:05 +00:00
" inappropriate matrix size - expects 3x3 or 4x4 matrix " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2010-02-20 19:49:04 +00:00
2011-10-13 01:29:08 +00:00
if ( order_str ) {
2011-09-19 14:29:21 +00:00
order = euler_order_from_string ( order_str , " Matrix.to_euler() " ) ;
2010-02-20 19:49:04 +00:00
2011-10-13 01:29:08 +00:00
if ( order = = - 1 )
2010-02-20 19:49:04 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( eul_compat ) {
if ( order = = 1 ) mat3_to_compatible_eul ( eul , eul_compatf , mat ) ;
2010-02-20 19:49:04 +00:00
else mat3_to_compatible_eulO ( eul , eul_compatf , order , mat ) ;
}
else {
2011-10-13 01:29:08 +00:00
if ( order = = 1 ) mat3_to_eul ( eul , mat ) ;
2010-02-20 19:49:04 +00:00
else mat3_to_eulO ( eul , order , mat ) ;
2009-06-17 20:33:34 +00:00
}
2010-02-20 19:49:04 +00:00
2011-11-24 04:45:36 +00:00
return Euler_CreatePyObject ( eul , order , Py_NEW , NULL ) ;
2009-06-17 20:33:34 +00:00
}
2011-02-05 06:14:50 +00:00
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_resize_4x4_doc ,
2011-02-05 06:14:50 +00:00
" .. method:: resize_4x4() \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" \n "
" Resize the matrix to 4x4. \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_resize_4x4 ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
int x , first_row_elem , curr_pos , new_pos , blank_columns , blank_rows , index ;
2011-10-13 01:29:08 +00:00
if ( self - > wrapped = = Py_WRAP ) {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.resize_4x4(): "
2011-07-14 01:25:05 +00:00
" cannot resize wrapped data - make a copy and resize that " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( self - > cb_user ) {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.resize_4x4(): "
2011-07-14 01:25:05 +00:00
" cannot resize owned data - make a copy and resize that " ) ;
2009-06-23 13:34:45 +00:00
return NULL ;
}
2011-02-04 03:06:23 +00:00
2009-06-23 13:34:45 +00:00
self - > contigPtr = PyMem_Realloc ( self - > contigPtr , ( sizeof ( float ) * 16 ) ) ;
2011-10-13 01:29:08 +00:00
if ( self - > contigPtr = = NULL ) {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_MemoryError ,
2011-09-19 14:29:21 +00:00
" Matrix.resize_4x4(): "
" problem allocating pointer space " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-12-19 03:12:10 +00:00
2009-06-17 20:33:34 +00:00
/*move data to new spot in array + clean*/
2011-10-13 01:29:08 +00:00
for ( blank_rows = ( 4 - self - > row_size ) ; blank_rows > 0 ; blank_rows - - ) {
for ( x = 0 ; x < 4 ; x + + ) {
2011-02-09 09:20:17 +00:00
index = ( 4 * ( self - > row_size + ( blank_rows - 1 ) ) ) + x ;
2011-10-13 01:29:08 +00:00
if ( index = = 10 | | index = = 15 ) {
2009-06-17 20:33:34 +00:00
self - > contigPtr [ index ] = 1.0f ;
2011-03-19 11:12:48 +00:00
}
else {
2009-06-17 20:33:34 +00:00
self - > contigPtr [ index ] = 0.0f ;
}
}
}
2011-10-13 01:29:08 +00:00
for ( x = 1 ; x < = self - > row_size ; x + + ) {
2011-02-09 09:20:17 +00:00
first_row_elem = ( self - > col_size * ( self - > row_size - x ) ) ;
curr_pos = ( first_row_elem + ( self - > col_size - 1 ) ) ;
2011-03-19 11:12:48 +00:00
new_pos = ( 4 * ( self - > row_size - x ) ) + ( curr_pos - first_row_elem ) ;
2011-10-13 01:29:08 +00:00
for ( blank_columns = ( 4 - self - > col_size ) ; blank_columns > 0 ; blank_columns - - ) {
2009-06-17 20:33:34 +00:00
self - > contigPtr [ new_pos + blank_columns ] = 0.0f ;
}
2011-10-13 01:29:08 +00:00
for ( ; curr_pos > = first_row_elem ; curr_pos - - ) {
2009-06-17 20:33:34 +00:00
self - > contigPtr [ new_pos ] = self - > contigPtr [ curr_pos ] ;
new_pos - - ;
}
}
2011-02-09 09:20:17 +00:00
self - > row_size = 4 ;
self - > col_size = 4 ;
2011-02-04 03:06:23 +00:00
2011-02-05 09:57:02 +00:00
Py_RETURN_NONE ;
2009-06-17 20:33:34 +00:00
}
2010-02-23 09:39:47 +00:00
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_to_4x4_doc ,
2010-02-23 09:39:47 +00:00
" .. method:: to_4x4() \n "
" \n "
" Return a 4x4 copy of this matrix. \n "
" \n "
" :return: a new matrix. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_to_4x4 ( MatrixObject * self )
2010-02-23 09:39:47 +00:00
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2010-02-23 09:39:47 +00:00
return NULL ;
2011-10-13 01:29:08 +00:00
if ( self - > col_size = = 4 & & self - > row_size = = 4 ) {
2011-11-29 20:22:35 +00:00
return Matrix_CreatePyObject ( self - > contigPtr , 4 , 4 , Py_NEW , Py_TYPE ( self ) ) ;
2010-02-23 09:39:47 +00:00
}
2011-10-13 01:29:08 +00:00
else if ( self - > col_size = = 3 & & self - > row_size = = 3 ) {
2010-02-23 09:39:47 +00:00
float mat [ 4 ] [ 4 ] ;
copy_m4_m3 ( mat , ( float ( * ) [ 3 ] ) self - > contigPtr ) ;
2011-11-29 20:22:35 +00:00
return Matrix_CreatePyObject ( ( float * ) mat , 4 , 4 , Py_NEW , Py_TYPE ( self ) ) ;
2010-02-23 09:39:47 +00:00
}
/* TODO, 2x2 matrix */
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.to_4x4(): "
" inappropriate matrix size " ) ;
2010-02-23 09:39:47 +00:00
return NULL ;
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_to_3x3_doc ,
2010-02-23 09:39:47 +00:00
" .. method:: to_3x3() \n "
" \n "
" Return a 3x3 copy of this matrix. \n "
" \n "
" :return: a new matrix. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_to_3x3 ( MatrixObject * self )
2010-02-23 09:39:47 +00:00
{
2011-01-25 16:32:41 +00:00
float mat [ 3 ] [ 3 ] ;
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2010-02-23 09:39:47 +00:00
return NULL ;
2011-10-13 01:29:08 +00:00
if ( ( self - > col_size < 3 ) | | ( self - > row_size < 3 ) ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.to_3x3(): inappropriate matrix size " ) ;
2011-01-25 16:32:41 +00:00
return NULL ;
2010-02-23 09:39:47 +00:00
}
2011-01-25 16:32:41 +00:00
matrix_as_3x3 ( mat , self ) ;
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( ( float * ) mat , 3 , 3 , Py_NEW , Py_TYPE ( self ) ) ;
2010-02-23 09:39:47 +00:00
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_to_translation_doc ,
2011-02-05 06:14:50 +00:00
" .. method:: to_translation() \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" \n "
" Return a the translation part of a 4 row matrix. \n "
2010-01-27 21:33:39 +00:00
" \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" :return: Return a the translation of a matrix. \n "
2011-01-07 06:39:48 +00:00
" :rtype: :class:`Vector` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_to_translation ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( ( self - > col_size < 3 ) | | self - > row_size < 4 ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.to_translation(): "
2011-07-14 01:25:05 +00:00
" inappropriate matrix size " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-12-19 03:12:10 +00:00
return Vector_CreatePyObject ( MATRIX_ROW_PTR ( self , 3 ) , 3 , Py_NEW , NULL ) ;
2009-06-17 20:33:34 +00:00
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_to_scale_doc ,
2011-02-05 06:14:50 +00:00
" .. method:: to_scale() \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" \n "
" Return a the scale part of a 3x3 or 4x4 matrix. \n "
2010-01-27 21:33:39 +00:00
" \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" :return: Return a the scale of a matrix. \n "
2010-01-27 21:33:39 +00:00
" :rtype: :class:`Vector` \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" \n "
2011-02-04 09:35:20 +00:00
" .. note:: This method does not return negative a scale on any axis because it is not possible to obtain this data from the matrix alone. \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_to_scale ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-01-25 16:32:41 +00:00
float rot [ 3 ] [ 3 ] ;
float mat [ 3 ] [ 3 ] ;
float size [ 3 ] ;
2009-06-17 20:33:34 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-01-25 16:32:41 +00:00
2009-06-17 20:33:34 +00:00
/*must be 3-4 cols, 3-4 rows, square matrix*/
2011-10-13 01:29:08 +00:00
if ( ( self - > col_size < 3 ) | | ( self - > row_size < 3 ) ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.to_scale(): "
2011-07-14 01:25:05 +00:00
" inappropriate matrix size, 3x3 minimum size " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-01-25 16:32:41 +00:00
matrix_as_3x3 ( mat , self ) ;
/* compatible mat4_to_loc_rot_size */
mat3_to_rot_size ( rot , size , mat ) ;
2011-11-24 04:45:36 +00:00
return Vector_CreatePyObject ( size , 3 , Py_NEW , NULL ) ;
2009-06-17 20:33:34 +00:00
}
2010-10-26 12:48:07 +00:00
2011-07-14 01:25:05 +00:00
/*---------------------------matrix.invert() ---------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_invert_doc ,
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" .. method:: invert() \n "
" \n "
" Set the matrix to its inverse. \n "
2010-01-27 21:33:39 +00:00
" \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" .. note:: :exc:`ValueError` exception is raised. \n "
" \n "
2011-02-04 09:35:20 +00:00
" .. seealso:: <http://en.wikipedia.org/wiki/Inverse_matrix> \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_invert ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-02-04 03:06:23 +00:00
2009-06-17 20:33:34 +00:00
int x , y , z = 0 ;
float det = 0.0f ;
2011-11-16 03:56:34 +00:00
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 } ;
2009-06-17 20:33:34 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-10-13 01:29:08 +00:00
if ( self - > row_size ! = self - > col_size ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.invert(ed): "
2011-07-14 01:25:05 +00:00
" only square matrices are supported " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
/*calculate the determinant*/
2011-02-04 03:06:23 +00:00
det = matrix_determinant_internal ( self ) ;
2009-06-17 20:33:34 +00:00
2011-10-13 01:29:08 +00:00
if ( det ! = 0 ) {
2009-06-17 20:33:34 +00:00
/*calculate the classical adjoint*/
2011-10-13 01:29:08 +00:00
if ( self - > row_size = = 2 ) {
2011-12-19 03:12:10 +00:00
mat [ 0 ] = MATRIX_ITEM ( self , 1 , 1 ) ;
mat [ 1 ] = - MATRIX_ITEM ( self , 0 , 1 ) ;
mat [ 2 ] = - MATRIX_ITEM ( self , 1 , 0 ) ;
mat [ 3 ] = MATRIX_ITEM ( self , 0 , 0 ) ;
2011-11-16 03:56:34 +00:00
}
else if ( self - > row_size = = 3 ) {
2010-02-23 09:39:47 +00:00
adjoint_m3_m3 ( ( float ( * ) [ 3 ] ) mat , ( float ( * ) [ 3 ] ) self - > contigPtr ) ;
2011-11-16 03:56:34 +00:00
}
else if ( self - > row_size = = 4 ) {
2010-02-23 09:39:47 +00:00
adjoint_m4_m4 ( ( float ( * ) [ 4 ] ) mat , ( float ( * ) [ 4 ] ) self - > contigPtr ) ;
2009-06-17 20:33:34 +00:00
}
/*divide by determinate*/
2011-10-13 01:29:08 +00:00
for ( x = 0 ; x < ( self - > row_size * self - > col_size ) ; x + + ) {
2009-06-17 20:33:34 +00:00
mat [ x ] / = det ;
}
/*set values*/
2011-10-13 01:29:08 +00:00
for ( x = 0 ; x < self - > row_size ; x + + ) {
for ( y = 0 ; y < self - > col_size ; y + + ) {
2011-12-19 03:12:10 +00:00
MATRIX_ITEM ( self , x , y ) = mat [ z ] ;
2009-06-17 20:33:34 +00:00
z + + ;
}
}
/*transpose
2011-02-04 03:06:23 +00:00
Matrix_transpose ( self ) ; */
2011-07-14 01:25:05 +00:00
}
else {
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.invert(ed): "
2011-07-14 01:25:05 +00:00
" matrix does not have an inverse " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-02-04 03:06:23 +00:00
2010-10-20 12:11:09 +00:00
( void ) BaseMath_WriteCallback ( self ) ;
2011-02-05 06:14:50 +00:00
Py_RETURN_NONE ;
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_inverted_doc ,
2011-02-09 09:20:17 +00:00
" .. method:: inverted() \n "
2011-02-05 06:14:50 +00:00
" \n "
" Return an inverted copy of the matrix. \n "
" \n "
" :return: the inverted matrix. \n "
" :rtype: :class:`Matrix` \n "
" \n "
" .. note:: :exc:`ValueError` exception is raised. \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_inverted ( MatrixObject * self )
{
2011-02-09 09:20:17 +00:00
return matrix__apply_to_copy ( ( PyNoArgsFunction ) Matrix_invert , self ) ;
2009-06-17 20:33:34 +00:00
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_rotate_doc ,
2011-02-05 09:57:02 +00:00
" .. method:: rotate(other) \n "
" \n "
" Rotates the matrix 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 "
" \n "
" .. note:: If any of the columns are not unit length this may not have desired results. \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 09:57:02 +00:00
static PyObject * Matrix_rotate ( MatrixObject * self , PyObject * value )
{
float self_rmat [ 3 ] [ 3 ] , other_rmat [ 3 ] [ 3 ] , rmat [ 3 ] [ 3 ] ;
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2011-02-05 09:57:02 +00:00
return NULL ;
2011-10-13 01:29:08 +00:00
if ( mathutils_any_to_rotmat ( other_rmat , value , " matrix.rotate(value) " ) = = - 1 )
2011-02-05 09:57:02 +00:00
return NULL ;
2011-10-13 01:29:08 +00:00
if ( self - > col_size ! = 3 | | self - > row_size ! = 3 ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.rotate(): "
" must have 3x3 dimensions " ) ;
2011-02-05 09:57:02 +00:00
return NULL ;
}
matrix_as_3x3 ( self_rmat , self ) ;
2011-11-24 19:36:12 +00:00
mul_m3_m3m3 ( rmat , other_rmat , self_rmat ) ;
2011-02-05 09:57:02 +00:00
copy_m3_m3 ( ( float ( * ) [ 3 ] ) ( self - > contigPtr ) , rmat ) ;
( void ) BaseMath_WriteCallback ( self ) ;
Py_RETURN_NONE ;
}
2011-07-14 01:25:05 +00:00
/*---------------------------matrix.decompose() ---------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_decompose_doc ,
2010-10-26 12:48:07 +00:00
" .. method:: decompose() \n "
" \n "
" Return the location, rotaion and scale components of this matrix. \n "
" \n "
" :return: loc, rot, scale triple. \n "
2011-02-04 09:35:20 +00:00
" :rtype: (:class:`Vector`, :class:`Quaternion`, :class:`Vector`) "
2011-05-24 16:05:51 +00:00
) ;
2011-02-04 03:06:23 +00:00
static PyObject * Matrix_decompose ( MatrixObject * self )
2010-10-26 12:48:07 +00:00
{
PyObject * ret ;
float loc [ 3 ] ;
float rot [ 3 ] [ 3 ] ;
float quat [ 4 ] ;
float size [ 3 ] ;
2011-10-13 01:29:08 +00:00
if ( self - > col_size ! = 4 | | self - > row_size ! = 4 ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.decompose(): "
2011-07-14 01:25:05 +00:00
" inappropriate matrix size - expects 4x4 matrix " ) ;
2010-10-26 12:48:07 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2010-10-26 12:48:07 +00:00
return NULL ;
mat4_to_loc_rot_size ( loc , rot , size , ( float ( * ) [ 4 ] ) self - > contigPtr ) ;
mat3_to_quat ( quat , rot ) ;
ret = PyTuple_New ( 3 ) ;
2011-11-24 04:45:36 +00:00
PyTuple_SET_ITEM ( ret , 0 , Vector_CreatePyObject ( loc , 3 , Py_NEW , NULL ) ) ;
PyTuple_SET_ITEM ( ret , 1 , Quaternion_CreatePyObject ( quat , Py_NEW , NULL ) ) ;
PyTuple_SET_ITEM ( ret , 2 , Vector_CreatePyObject ( size , 3 , Py_NEW , NULL ) ) ;
2010-10-26 12:48:07 +00:00
return ret ;
}
2009-06-17 20:33:34 +00:00
2010-11-22 10:39:28 +00:00
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_lerp_doc ,
2010-11-22 10:39:28 +00:00
" .. function:: lerp(other, factor) \n "
" \n "
2011-10-17 02:20:53 +00:00
" Returns the interpolation of two matrices. \n "
2010-11-22 10:39:28 +00:00
" \n "
" :arg other: value to interpolate with. \n "
" :type other: :class:`Matrix` \n "
" :arg factor: The interpolation value in [0.0, 1.0]. \n "
" :type factor: float \n "
" :return: The interpolated rotation. \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-04 03:06:23 +00:00
static PyObject * Matrix_lerp ( MatrixObject * self , PyObject * args )
2010-11-22 10:39:28 +00:00
{
MatrixObject * mat2 = NULL ;
float fac , mat [ MATRIX_MAX_DIM * MATRIX_MAX_DIM ] ;
2011-10-13 01:29:08 +00:00
if ( ! PyArg_ParseTuple ( args , " O!f:lerp " , & matrix_Type , & mat2 , & fac ) )
2010-11-22 10:39:28 +00:00
return NULL ;
2011-10-13 01:29:08 +00:00
if ( self - > row_size ! = mat2 - > row_size | | self - > col_size ! = mat2 - > col_size ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.lerp(): "
2011-07-14 01:25:05 +00:00
" expects both matrix objects of the same dimensions " ) ;
2010-11-22 10:39:28 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 | | BaseMath_ReadCallback ( mat2 ) = = - 1 )
2010-11-22 10:39:28 +00:00
return NULL ;
/* TODO, different sized matrix */
2011-10-13 01:29:08 +00:00
if ( self - > row_size = = 4 & & self - > col_size = = 4 ) {
2010-11-22 10:39:28 +00:00
blend_m4_m4m4 ( ( float ( * ) [ 4 ] ) mat , ( float ( * ) [ 4 ] ) self - > contigPtr , ( float ( * ) [ 4 ] ) mat2 - > contigPtr , fac ) ;
}
2011-02-09 09:20:17 +00:00
else if ( self - > row_size = = 3 & & self - > col_size = = 3 ) {
2010-11-22 10:39:28 +00:00
blend_m3_m3m3 ( ( float ( * ) [ 3 ] ) mat , ( float ( * ) [ 3 ] ) self - > contigPtr , ( float ( * ) [ 3 ] ) mat2 - > contigPtr , fac ) ;
}
else {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-09-19 14:29:21 +00:00
" Matrix.lerp(): "
2011-07-14 01:25:05 +00:00
" only 3x3 and 4x4 matrices supported " ) ;
2010-11-22 10:39:28 +00:00
return NULL ;
}
2011-11-29 20:22:35 +00:00
return Matrix_CreatePyObject ( mat , self - > row_size , self - > col_size , Py_NEW , Py_TYPE ( self ) ) ;
2010-11-22 10:39:28 +00:00
}
2011-07-14 01:25:05 +00:00
/*---------------------------matrix.determinant() ----------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_determinant_doc ,
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" .. method:: determinant() \n "
" \n "
" Return the determinant of a matrix. \n "
2010-01-27 21:33:39 +00:00
" \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" :return: Return a the determinant of a matrix. \n "
" :rtype: float \n "
" \n "
2011-02-04 09:35:20 +00:00
" .. seealso:: <http://en.wikipedia.org/wiki/Determinant> \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_determinant ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( self - > row_size ! = self - > col_size ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.determinant(): "
2011-07-14 01:25:05 +00:00
" only square matrices are supported " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-02-04 03:06:23 +00:00
return PyFloat_FromDouble ( ( double ) matrix_determinant_internal ( self ) ) ;
2009-06-17 20:33:34 +00:00
}
2011-07-14 01:25:05 +00:00
/*---------------------------matrix.transpose() ------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_transpose_doc ,
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" .. method:: transpose() \n "
" \n "
" Set the matrix to its transpose. \n "
2010-01-27 21:33:39 +00:00
" \n "
2011-02-04 09:35:20 +00:00
" .. seealso:: <http://en.wikipedia.org/wiki/Transpose> \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_transpose ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( self - > row_size ! = self - > col_size ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.transpose(d): "
2011-07-14 01:25:05 +00:00
" only square matrices are supported " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( self - > row_size = = 2 ) {
2011-12-19 03:12:10 +00:00
const float t = MATRIX_ITEM ( self , 1 , 0 ) ;
MATRIX_ITEM ( self , 1 , 0 ) = MATRIX_ITEM ( self , 0 , 1 ) ;
MATRIX_ITEM ( self , 0 , 1 ) = t ;
2011-11-16 03:56:34 +00:00
}
else if ( self - > row_size = = 3 ) {
2010-02-23 09:39:47 +00:00
transpose_m3 ( ( float ( * ) [ 3 ] ) self - > contigPtr ) ;
2011-07-14 01:25:05 +00:00
}
else {
2010-02-23 09:39:47 +00:00
transpose_m4 ( ( float ( * ) [ 4 ] ) self - > contigPtr ) ;
2009-06-17 20:33:34 +00:00
}
2010-10-20 12:11:09 +00:00
( void ) BaseMath_WriteCallback ( self ) ;
2011-02-05 06:14:50 +00:00
Py_RETURN_NONE ;
2009-06-17 20:33:34 +00:00
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_transposed_doc ,
2011-02-05 06:14:50 +00:00
" .. method:: transposed() \n "
" \n "
" Return a new, transposed matrix. \n "
" \n "
" :return: a transposed matrix \n "
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_transposed ( MatrixObject * self )
{
2011-02-09 09:20:17 +00:00
return matrix__apply_to_copy ( ( PyNoArgsFunction ) Matrix_transpose , self ) ;
2011-02-05 06:14:50 +00:00
}
2009-06-17 20:33:34 +00:00
2011-07-14 01:25:05 +00:00
/*---------------------------matrix.zero() -----------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_zero_doc ,
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" .. method:: zero() \n "
" \n "
" Set all the matrix values to zero. \n "
2010-01-27 21:33:39 +00:00
" \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" :return: an instance of itself \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_zero ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-11-24 04:12:16 +00:00
fill_vn_fl ( self - > contigPtr , self - > row_size * self - > col_size , 0.0f ) ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_WriteCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-02-05 06:14:50 +00:00
Py_RETURN_NONE ;
2009-06-17 20:33:34 +00:00
}
2011-07-14 01:25:05 +00:00
/*---------------------------matrix.identity(() ------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_identity_doc ,
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" .. method:: identity() \n "
" \n "
" Set the matrix to the identity matrix. \n "
2010-01-27 21:33:39 +00:00
" \n "
2011-05-26 19:13:01 +00:00
" .. note:: An object with zero location and rotation, a scale of one, \n "
" will have an identity matrix. \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" \n "
2011-02-04 09:35:20 +00:00
" .. seealso:: <http://en.wikipedia.org/wiki/Identity_matrix> \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_identity ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( self - > row_size ! = self - > col_size ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-09-19 14:29:21 +00:00
" Matrix.identity(): "
2011-07-14 01:25:05 +00:00
" only square matrices are supported " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( self - > row_size = = 2 ) {
2011-12-19 03:12:10 +00:00
MATRIX_ITEM ( self , 0 , 0 ) = 1.0f ;
MATRIX_ITEM ( self , 0 , 1 ) = 0.0f ;
MATRIX_ITEM ( self , 1 , 0 ) = 0.0f ;
MATRIX_ITEM ( self , 1 , 1 ) = 1.0f ;
2011-11-16 03:56:34 +00:00
}
else if ( self - > row_size = = 3 ) {
2010-02-23 09:39:47 +00:00
unit_m3 ( ( float ( * ) [ 3 ] ) self - > contigPtr ) ;
2011-07-14 01:25:05 +00:00
}
else {
2010-02-23 09:39:47 +00:00
unit_m4 ( ( float ( * ) [ 4 ] ) self - > contigPtr ) ;
2009-06-17 20:33:34 +00:00
}
2011-10-13 01:29:08 +00:00
if ( BaseMath_WriteCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-02-05 06:14:50 +00:00
Py_RETURN_NONE ;
2009-06-17 20:33:34 +00:00
}
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
/*---------------------------Matrix.copy() ------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( Matrix_copy_doc ,
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" .. method:: copy() \n "
" \n "
" Returns a copy of this matrix. \n "
2010-01-27 21:33:39 +00:00
" \n "
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
" :return: an instance of itself \n "
2011-02-04 09:35:20 +00:00
" :rtype: :class:`Matrix` \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-05 06:14:50 +00:00
static PyObject * Matrix_copy ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-11-29 20:22:35 +00:00
return Matrix_CreatePyObject ( ( float ( * ) ) self - > contigPtr , self - > row_size , self - > col_size , Py_NEW , Py_TYPE ( self ) ) ;
2009-06-17 20:33:34 +00:00
}
/*----------------------------print object (internal)-------------*/
/*print the object to screen*/
2011-02-04 03:06:23 +00:00
static PyObject * Matrix_repr ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
int x , y ;
2011-02-13 10:52:18 +00:00
PyObject * rows [ MATRIX_MAX_DIM ] = { NULL } ;
2009-06-17 20:33:34 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2010-04-19 22:02:53 +00:00
2011-10-13 01:29:08 +00:00
for ( x = 0 ; x < self - > row_size ; x + + ) {
2011-02-09 09:20:17 +00:00
rows [ x ] = PyTuple_New ( self - > col_size ) ;
2011-10-13 01:29:08 +00:00
for ( y = 0 ; y < self - > col_size ; y + + ) {
2011-12-19 03:12:10 +00:00
PyTuple_SET_ITEM ( rows [ x ] , y , PyFloat_FromDouble ( MATRIX_ITEM ( self , x , y ) ) ) ;
2009-06-17 20:33:34 +00:00
}
}
2011-12-18 08:50:06 +00:00
switch ( self - > row_size ) {
2011-07-21 02:00:29 +00:00
case 2 : return PyUnicode_FromFormat ( " Matrix((%R, \n "
" %R)) " , rows [ 0 ] , rows [ 1 ] ) ;
bugfix [#24665] mathutils.Matrix initialization is counter-intuitive and generates bugs
was printing transposed, also nicer printing.
>>> from mathutils import Matrix
>>> Matrix()
Matrix((1.0, 0.0, 0.0, 0.0),
(0.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 1.0, 0.0),
(0.0, 0.0, 0.0, 1.0))
was...
Matrix((1.000000, 0.000000, 0.000000, 0.000000), (0.000000, 1.000000, 0.000000, 0.000000), (0.000000, 0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000, 1.000000))
2010-11-12 02:50:57 +00:00
2011-07-21 02:00:29 +00:00
case 3 : return PyUnicode_FromFormat ( " Matrix((%R, \n "
" %R, \n "
" %R)) " , rows [ 0 ] , rows [ 1 ] , rows [ 2 ] ) ;
bugfix [#24665] mathutils.Matrix initialization is counter-intuitive and generates bugs
was printing transposed, also nicer printing.
>>> from mathutils import Matrix
>>> Matrix()
Matrix((1.0, 0.0, 0.0, 0.0),
(0.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 1.0, 0.0),
(0.0, 0.0, 0.0, 1.0))
was...
Matrix((1.000000, 0.000000, 0.000000, 0.000000), (0.000000, 1.000000, 0.000000, 0.000000), (0.000000, 0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000, 1.000000))
2010-11-12 02:50:57 +00:00
2011-07-21 02:00:29 +00:00
case 4 : return PyUnicode_FromFormat ( " Matrix((%R, \n "
" %R, \n "
" %R, \n "
" %R)) " , rows [ 0 ] , rows [ 1 ] , rows [ 2 ] , rows [ 3 ] ) ;
bugfix [#24665] mathutils.Matrix initialization is counter-intuitive and generates bugs
was printing transposed, also nicer printing.
>>> from mathutils import Matrix
>>> Matrix()
Matrix((1.0, 0.0, 0.0, 0.0),
(0.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 1.0, 0.0),
(0.0, 0.0, 0.0, 1.0))
was...
Matrix((1.000000, 0.000000, 0.000000, 0.000000), (0.000000, 1.000000, 0.000000, 0.000000), (0.000000, 0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000, 1.000000))
2010-11-12 02:50:57 +00:00
}
2009-06-17 20:33:34 +00:00
2011-07-21 02:00:29 +00:00
Py_FatalError ( " Matrix(): invalid row size! " ) ;
bugfix [#24665] mathutils.Matrix initialization is counter-intuitive and generates bugs
was printing transposed, also nicer printing.
>>> from mathutils import Matrix
>>> Matrix()
Matrix((1.0, 0.0, 0.0, 0.0),
(0.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 1.0, 0.0),
(0.0, 0.0, 0.0, 1.0))
was...
Matrix((1.000000, 0.000000, 0.000000, 0.000000), (0.000000, 1.000000, 0.000000, 0.000000), (0.000000, 0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000, 1.000000))
2010-11-12 02:50:57 +00:00
return NULL ;
2009-06-17 20:33:34 +00:00
}
bugfix [#24665] mathutils.Matrix initialization is counter-intuitive and generates bugs
was printing transposed, also nicer printing.
>>> from mathutils import Matrix
>>> Matrix()
Matrix((1.0, 0.0, 0.0, 0.0),
(0.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 1.0, 0.0),
(0.0, 0.0, 0.0, 1.0))
was...
Matrix((1.000000, 0.000000, 0.000000, 0.000000), (0.000000, 1.000000, 0.000000, 0.000000), (0.000000, 0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000, 1.000000))
2010-11-12 02:50:57 +00:00
2011-02-05 10:40:42 +00:00
static PyObject * Matrix_richcmpr ( PyObject * a , PyObject * b , int op )
2009-06-17 20:33:34 +00:00
{
2011-02-05 10:40:42 +00:00
PyObject * res ;
int ok = - 1 ; /* zero is true */
2009-06-17 20:33:34 +00:00
2011-02-05 10:40:42 +00:00
if ( MatrixObject_Check ( a ) & & MatrixObject_Check ( b ) ) {
MatrixObject * matA = ( MatrixObject * ) a ;
MatrixObject * matB = ( MatrixObject * ) b ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( matA ) = = - 1 | | BaseMath_ReadCallback ( matB ) = = - 1 )
2011-02-05 10:40:42 +00:00
return NULL ;
2009-06-17 20:33:34 +00:00
2011-02-09 09:20:17 +00:00
ok = ( ( matA - > col_size = = matB - > col_size ) & &
( matA - > row_size = = matB - > row_size ) & &
EXPP_VectorsAreEqual ( matA - > contigPtr , matB - > contigPtr , ( matA - > row_size * matA - > col_size ) , 1 )
2011-02-05 10:40:42 +00:00
) ? 0 : - 1 ;
}
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 ;
2009-06-17 20:33:34 +00:00
}
2011-02-05 10:40:42 +00:00
return Py_INCREF ( res ) , res ;
2009-06-17 20:33:34 +00:00
}
2009-06-30 00:42:17 +00:00
2009-06-17 20:33:34 +00:00
/*---------------------SEQUENCE PROTOCOLS------------------------
- - - - - - - - - - - - - - - - - - - - - - - - - - - - len ( object ) - - - - - - - - - - - - - - - - - - - - - - - -
sequence length */
2011-02-04 03:06:23 +00:00
static int Matrix_len ( MatrixObject * self )
2009-06-17 20:33:34 +00:00
{
2011-02-09 09:20:17 +00:00
return ( self - > row_size ) ;
2009-06-17 20:33:34 +00:00
}
/*----------------------------object[]---------------------------
sequence accessor ( get )
the wrapped vector gives direct access to the matrix data */
2011-02-04 03:06:23 +00:00
static PyObject * Matrix_item ( MatrixObject * self , int i )
2009-06-17 20:33:34 +00:00
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( i < 0 | | i > = self - > row_size ) {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_IndexError ,
" matrix[attribute]: "
" array index out of range " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-11-24 04:45:36 +00:00
return Vector_CreatePyObject_cb ( ( PyObject * ) self , self - > col_size , mathutils_matrix_vector_cb_index , i ) ;
2009-06-17 20:33:34 +00:00
}
/*----------------------------object[]-------------------------
2011-01-09 12:09:54 +00:00
sequence accessor ( set ) */
static int Matrix_ass_item ( MatrixObject * self , int i , PyObject * value )
2009-06-17 20:33:34 +00:00
{
float vec [ 4 ] ;
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return - 1 ;
2011-01-09 12:09:54 +00:00
2011-10-13 01:29:08 +00:00
if ( i > = self - > row_size | | i < 0 ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_IndexError ,
2011-07-14 01:25:05 +00:00
" matrix[attribute] = x: bad column " ) ;
2009-06-17 20:33:34 +00:00
return - 1 ;
}
2011-10-13 01:29:08 +00:00
if ( mathutils_array_parse ( vec , self - > col_size , self - > col_size , value , " matrix[i] = value assignment " ) < 0 ) {
2009-06-17 20:33:34 +00:00
return - 1 ;
}
2011-01-09 12:09:54 +00:00
2011-12-19 03:12:10 +00:00
memcpy ( MATRIX_ROW_PTR ( self , i ) , vec , self - > col_size * sizeof ( float ) ) ;
2011-01-09 12:09:54 +00:00
( void ) BaseMath_WriteCallback ( self ) ;
return 0 ;
2009-06-17 20:33:34 +00:00
}
2011-01-09 12:09:54 +00:00
2009-06-17 20:33:34 +00:00
/*----------------------------object[z:y]------------------------
sequence slice ( get ) */
2011-02-04 03:06:23 +00:00
static PyObject * Matrix_slice ( MatrixObject * self , int begin , int end )
2009-06-17 20:33:34 +00:00
{
2010-12-24 03:51:34 +00:00
PyObject * tuple ;
2009-06-17 20:33:34 +00:00
int count ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2009-06-17 20:33:34 +00:00
2011-02-09 09:20:17 +00:00
CLAMP ( begin , 0 , self - > row_size ) ;
CLAMP ( end , 0 , self - > row_size ) ;
2011-03-19 11:12:48 +00:00
begin = MIN2 ( begin , end ) ;
2009-06-17 20:33:34 +00:00
2010-12-24 03:51:34 +00:00
tuple = PyTuple_New ( end - begin ) ;
2011-10-13 01:29:08 +00:00
for ( count = begin ; count < end ; count + + ) {
2010-12-24 03:51:34 +00:00
PyTuple_SET_ITEM ( tuple , count - begin ,
2011-11-24 04:45:36 +00:00
Vector_CreatePyObject_cb ( ( PyObject * ) self , self - > col_size , mathutils_matrix_vector_cb_index , count ) ) ;
2009-06-23 13:34:45 +00:00
2009-06-17 20:33:34 +00:00
}
2010-12-24 03:51:34 +00:00
return tuple ;
2009-06-17 20:33:34 +00:00
}
/*----------------------------object[z:y]------------------------
sequence slice ( set ) */
2011-02-04 03:06:23 +00:00
static int Matrix_ass_slice ( MatrixObject * self , int begin , int end , PyObject * value )
2009-06-17 20:33:34 +00:00
{
2011-01-09 12:38:22 +00:00
PyObject * value_fast = NULL ;
2009-06-17 20:33:34 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return - 1 ;
2011-02-04 03:06:23 +00:00
2011-02-09 09:20:17 +00:00
CLAMP ( begin , 0 , self - > row_size ) ;
CLAMP ( end , 0 , self - > row_size ) ;
2011-03-19 11:12:48 +00:00
begin = MIN2 ( begin , end ) ;
2009-06-17 20:33:34 +00:00
2011-01-09 12:38:22 +00:00
/* non list/tuple cases */
2011-10-13 01:29:08 +00:00
if ( ! ( value_fast = PySequence_Fast ( value , " matrix[begin:end] = value " ) ) ) {
2011-01-09 12:38:22 +00:00
/* PySequence_Fast sets the error */
return - 1 ;
}
else {
2011-01-09 12:09:54 +00:00
const int size = end - begin ;
2011-01-09 12:38:22 +00:00
int i ;
float mat [ 16 ] ;
2011-01-09 12:09:54 +00:00
2011-10-13 01:29:08 +00:00
if ( PySequence_Fast_GET_SIZE ( value_fast ) ! = size ) {
2011-01-09 12:38:22 +00:00
Py_DECREF ( value_fast ) ;
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_ValueError ,
2011-07-14 01:25:05 +00:00
" matrix[begin:end] = []: "
" size mismatch in slice assignment " ) ;
2009-06-17 20:33:34 +00:00
return - 1 ;
}
2011-01-09 12:09:54 +00:00
2009-06-17 20:33:34 +00:00
/*parse sub items*/
for ( i = 0 ; i < size ; i + + ) {
/*parse each sub sequence*/
2011-01-09 12:38:22 +00:00
PyObject * item = PySequence_Fast_GET_ITEM ( value_fast , i ) ;
2009-06-17 20:33:34 +00:00
2011-11-29 20:22:35 +00:00
if ( mathutils_array_parse ( & mat [ i * self - > col_size ] , self - > col_size , self - > col_size , item ,
" matrix[begin:end] = value assignment " ) < 0 )
{
2009-06-17 20:33:34 +00:00
return - 1 ;
}
}
2011-01-09 12:09:54 +00:00
2011-01-09 12:38:22 +00:00
Py_DECREF ( value_fast ) ;
2009-06-17 20:33:34 +00:00
/*parsed well - now set in matrix*/
2011-02-09 09:20:17 +00:00
memcpy ( self - > contigPtr + ( begin * self - > col_size ) , mat , sizeof ( float ) * ( size * self - > col_size ) ) ;
2011-01-09 12:09:54 +00:00
2010-10-20 12:11:09 +00:00
( void ) BaseMath_WriteCallback ( self ) ;
2009-06-17 20:33:34 +00:00
return 0 ;
}
}
/*------------------------NUMERIC PROTOCOLS----------------------
- - - - - - - - - - - - - - - - - - - - - - - - obj + obj - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2011-02-04 03:06:23 +00:00
static PyObject * Matrix_add ( PyObject * m1 , PyObject * m2 )
2009-06-17 20:33:34 +00:00
{
2011-01-09 09:16:04 +00:00
float mat [ 16 ] ;
2009-06-17 20:33:34 +00:00
MatrixObject * mat1 = NULL , * mat2 = NULL ;
mat1 = ( MatrixObject * ) m1 ;
mat2 = ( MatrixObject * ) m2 ;
2011-10-13 01:29:08 +00:00
if ( ! MatrixObject_Check ( m1 ) | | ! MatrixObject_Check ( m2 ) ) {
2011-11-13 09:20:04 +00:00
PyErr_Format ( PyExc_TypeError ,
" Matrix addition: (%s + %s) "
" invalid type for this operation " ,
Py_TYPE ( m1 ) - > tp_name , Py_TYPE ( m2 ) - > tp_name ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( mat1 ) = = - 1 | | BaseMath_ReadCallback ( mat2 ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( mat1 - > row_size ! = mat2 - > row_size | | mat1 - > col_size ! = mat2 - > col_size ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-07-14 01:25:05 +00:00
" Matrix addition: "
" matrices must have the same dimensions for this operation " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-02-09 09:20:17 +00:00
add_vn_vnvn ( mat , mat1 - > contigPtr , mat2 - > contigPtr , mat1 - > row_size * mat1 - > col_size ) ;
2009-06-17 20:33:34 +00:00
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( mat , mat1 - > row_size , mat1 - > col_size , Py_NEW , Py_TYPE ( mat1 ) ) ;
2009-06-17 20:33:34 +00:00
}
/*------------------------obj - obj------------------------------
subtraction */
2011-02-04 03:06:23 +00:00
static PyObject * Matrix_sub ( PyObject * m1 , PyObject * m2 )
2009-06-17 20:33:34 +00:00
{
2011-01-09 09:16:04 +00:00
float mat [ 16 ] ;
2009-06-17 20:33:34 +00:00
MatrixObject * mat1 = NULL , * mat2 = NULL ;
mat1 = ( MatrixObject * ) m1 ;
mat2 = ( MatrixObject * ) m2 ;
2011-10-13 01:29:08 +00:00
if ( ! MatrixObject_Check ( m1 ) | | ! MatrixObject_Check ( m2 ) ) {
2011-11-13 09:20:04 +00:00
PyErr_Format ( PyExc_TypeError ,
" Matrix subtraction: (%s - %s) "
" invalid type for this operation " ,
Py_TYPE ( m1 ) - > tp_name , Py_TYPE ( m2 ) - > tp_name
) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( mat1 ) = = - 1 | | BaseMath_ReadCallback ( mat2 ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
2011-10-13 01:29:08 +00:00
if ( mat1 - > row_size ! = mat2 - > row_size | | mat1 - > col_size ! = mat2 - > col_size ) {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_TypeError ,
2011-07-14 01:25:05 +00:00
" Matrix addition: "
" matrices must have the same dimensions for this operation " ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
2011-02-09 09:20:17 +00:00
sub_vn_vnvn ( mat , mat1 - > contigPtr , mat2 - > contigPtr , mat1 - > row_size * mat1 - > col_size ) ;
2009-06-17 20:33:34 +00:00
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( mat , mat1 - > row_size , mat1 - > col_size , Py_NEW , Py_TYPE ( mat1 ) ) ;
2009-06-17 20:33:34 +00:00
}
/*------------------------obj * obj------------------------------
mulplication */
2011-01-09 09:16:04 +00:00
static PyObject * matrix_mul_float ( MatrixObject * mat , const float scalar )
{
float tmat [ 16 ] ;
2011-02-09 09:20:17 +00:00
mul_vn_vn_fl ( tmat , mat - > contigPtr , mat - > row_size * mat - > col_size , scalar ) ;
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( tmat , mat - > row_size , mat - > col_size , Py_NEW , Py_TYPE ( mat ) ) ;
2011-01-09 09:16:04 +00:00
}
2011-06-02 08:29:16 +00:00
static PyObject * Matrix_mul ( PyObject * m1 , PyObject * m2 )
2009-06-17 20:33:34 +00:00
{
float scalar ;
2011-01-09 09:16:04 +00:00
2009-06-17 20:33:34 +00:00
MatrixObject * mat1 = NULL , * mat2 = NULL ;
2011-10-13 01:29:08 +00:00
if ( MatrixObject_Check ( m1 ) ) {
2009-06-23 13:34:45 +00:00
mat1 = ( MatrixObject * ) m1 ;
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( mat1 ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
}
2011-10-13 01:29:08 +00:00
if ( MatrixObject_Check ( m2 ) ) {
2009-06-23 13:34:45 +00:00
mat2 = ( MatrixObject * ) m2 ;
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( mat2 ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
}
2009-06-17 20:33:34 +00:00
2011-10-13 01:29:08 +00:00
if ( mat1 & & mat2 ) {
2011-07-14 01:25:05 +00:00
/*MATRIX * MATRIX*/
2011-07-21 02:00:29 +00:00
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 } ;
double dot = 0.0f ;
int x , y , z ;
2011-10-13 01:29:08 +00:00
for ( x = 0 ; x < mat2 - > row_size ; x + + ) {
for ( y = 0 ; y < mat1 - > col_size ; y + + ) {
for ( z = 0 ; z < mat1 - > row_size ; z + + ) {
2011-12-19 03:12:10 +00:00
dot + = MATRIX_ITEM ( mat1 , z , y ) * MATRIX_ITEM ( mat2 , x , z ) ;
2009-06-17 20:33:34 +00:00
}
2011-07-21 02:00:29 +00:00
mat [ ( ( x * mat1 - > col_size ) + y ) ] = ( float ) dot ;
dot = 0.0f ;
2009-06-17 20:33:34 +00:00
}
}
2011-07-21 02:00:29 +00:00
2011-11-24 04:45:36 +00:00
return Matrix_CreatePyObject ( mat , mat2 - > row_size , mat1 - > col_size , Py_NEW , Py_TYPE ( mat1 ) ) ;
2009-06-18 23:12:29 +00:00
}
2011-10-13 01:29:08 +00:00
else if ( mat2 ) {
2011-07-14 01:25:05 +00:00
/*FLOAT/INT * MATRIX */
if ( ( ( scalar = PyFloat_AsDouble ( m1 ) ) = = - 1.0f & & PyErr_Occurred ( ) ) = = 0 ) {
2011-01-09 09:16:04 +00:00
return matrix_mul_float ( mat2 , scalar ) ;
2009-06-18 23:12:29 +00:00
}
2011-01-09 09:16:04 +00:00
}
2011-10-13 01:29:08 +00:00
else if ( mat1 ) {
2011-07-25 01:44:19 +00:00
/*VEC * MATRIX */
2011-10-13 01:29:08 +00:00
if ( VectorObject_Check ( m2 ) ) {
2011-07-25 01:44:19 +00:00
VectorObject * vec2 = ( VectorObject * ) m2 ;
float tvec [ 4 ] ;
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( vec2 ) = = - 1 )
2011-07-25 01:44:19 +00:00
return NULL ;
2011-10-13 01:29:08 +00:00
if ( column_vector_multiplication ( tvec , vec2 , mat1 ) = = - 1 ) {
2011-07-25 01:44:19 +00:00
return NULL ;
}
2011-11-24 04:45:36 +00:00
return Vector_CreatePyObject ( tvec , vec2 - > size , Py_NEW , Py_TYPE ( m2 ) ) ;
2011-07-25 01:44:19 +00:00
}
2011-07-14 01:25:05 +00:00
/*FLOAT/INT * MATRIX */
2011-07-25 01:44:19 +00:00
else if ( ( ( scalar = PyFloat_AsDouble ( m2 ) ) = = - 1.0f & & PyErr_Occurred ( ) ) = = 0 ) {
2011-01-09 09:16:04 +00:00
return matrix_mul_float ( mat1 , scalar ) ;
2009-06-17 20:33:34 +00:00
}
2011-01-09 09:16:04 +00:00
}
else {
2011-01-09 15:12:08 +00:00
BLI_assert ( ! " internal error " ) ;
2009-06-17 20:33:34 +00:00
}
2011-07-14 01:25:05 +00:00
PyErr_Format ( PyExc_TypeError ,
" Matrix multiplication: "
" not supported between '%.200s' and '%.200s' types " ,
Py_TYPE ( m1 ) - > tp_name , Py_TYPE ( m2 ) - > tp_name ) ;
2009-06-17 20:33:34 +00:00
return NULL ;
}
static PyObject * Matrix_inv ( MatrixObject * self )
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2009-06-23 13:34:45 +00:00
return NULL ;
2011-02-04 03:06:23 +00:00
return Matrix_invert ( self ) ;
2009-06-17 20:33:34 +00:00
}
/*-----------------PROTOCOL DECLARATIONS--------------------------*/
static PySequenceMethods Matrix_SeqMethods = {
2010-05-16 10:09:07 +00:00
( lenfunc ) Matrix_len , /* sq_length */
( binaryfunc ) NULL , /* sq_concat */
( ssizeargfunc ) NULL , /* sq_repeat */
( ssizeargfunc ) Matrix_item , /* sq_item */
2011-01-09 12:09:54 +00:00
( ssizessizeargfunc ) NULL , /* sq_slice, deprecated */
2010-05-16 10:09:07 +00:00
( ssizeobjargproc ) Matrix_ass_item , /* sq_ass_item */
2011-01-09 12:09:54 +00:00
( ssizessizeobjargproc ) NULL , /* sq_ass_slice, deprecated */
2010-05-16 10:09:07 +00:00
( objobjproc ) NULL , /* sq_contains */
( binaryfunc ) NULL , /* sq_inplace_concat */
( ssizeargfunc ) NULL , /* sq_inplace_repeat */
2009-06-17 20:33:34 +00:00
} ;
2009-06-28 13:27:06 +00:00
2009-07-01 13:31:36 +00:00
static PyObject * Matrix_subscript ( MatrixObject * 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 )
2011-02-09 09:20:17 +00:00
i + = self - > row_size ;
2009-07-01 13:31:36 +00:00
return Matrix_item ( self , i ) ;
2011-11-16 03:56:34 +00:00
}
else if ( PySlice_Check ( item ) ) {
2009-07-01 13:31:36 +00:00
Py_ssize_t start , stop , step , slicelength ;
2011-02-09 09:20:17 +00:00
if ( PySlice_GetIndicesEx ( ( void * ) item , self - > row_size , & start , & stop , & step , & slicelength ) < 0 )
2009-07-01 13:31:36 +00:00
return NULL ;
if ( slicelength < = 0 ) {
2011-02-04 03:39:06 +00:00
return PyTuple_New ( 0 ) ;
2009-07-01 13:31:36 +00:00
}
else if ( step = = 1 ) {
return Matrix_slice ( self , start , stop ) ;
}
else {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_IndexError ,
2011-10-17 02:20:53 +00:00
" slice steps not supported with matrices " ) ;
2009-07-01 13:31:36 +00:00
return NULL ;
}
}
else {
2011-07-14 01:25:05 +00:00
PyErr_Format ( PyExc_TypeError ,
2011-07-14 09:54:03 +00:00
" matrix indices must be integers, not %.200s " ,
2011-07-14 01:25:05 +00:00
Py_TYPE ( item ) - > tp_name ) ;
2009-07-01 13:31:36 +00:00
return NULL ;
}
}
static int Matrix_ass_subscript ( MatrixObject * 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 )
2011-02-09 09:20:17 +00:00
i + = self - > row_size ;
2009-07-01 13:31:36 +00:00
return Matrix_ass_item ( self , i , value ) ;
}
else if ( PySlice_Check ( item ) ) {
Py_ssize_t start , stop , step , slicelength ;
2011-02-09 09:20:17 +00:00
if ( PySlice_GetIndicesEx ( ( void * ) item , self - > row_size , & start , & stop , & step , & slicelength ) < 0 )
2009-07-01 13:31:36 +00:00
return - 1 ;
if ( step = = 1 )
return Matrix_ass_slice ( self , start , stop , value ) ;
else {
2011-07-14 09:54:03 +00:00
PyErr_SetString ( PyExc_IndexError ,
2011-10-17 02:20:53 +00:00
" slice steps not supported with matrices " ) ;
2009-07-01 13:31:36 +00:00
return - 1 ;
}
}
else {
2011-07-14 01:25:05 +00:00
PyErr_Format ( PyExc_TypeError ,
" matrix indices must be integers, not %.200s " ,
Py_TYPE ( item ) - > tp_name ) ;
2009-07-01 13:31:36 +00:00
return - 1 ;
}
}
static PyMappingMethods Matrix_AsMapping = {
( lenfunc ) Matrix_len ,
( binaryfunc ) Matrix_subscript ,
( objobjargproc ) Matrix_ass_subscript
} ;
2009-06-28 13:27:06 +00:00
static PyNumberMethods Matrix_NumMethods = {
( binaryfunc ) Matrix_add , /*nb_add*/
( binaryfunc ) Matrix_sub , /*nb_subtract*/
( binaryfunc ) Matrix_mul , /*nb_multiply*/
2011-02-13 10:52:18 +00:00
NULL , /*nb_remainder*/
NULL , /*nb_divmod*/
NULL , /*nb_power*/
2009-06-28 13:27:06 +00:00
( unaryfunc ) 0 , /*nb_negative*/
( unaryfunc ) 0 , /*tp_positive*/
( unaryfunc ) 0 , /*tp_absolute*/
( inquiry ) 0 , /*tp_bool*/
( unaryfunc ) Matrix_inv , /*nb_invert*/
2011-02-13 10:52:18 +00:00
NULL , /*nb_lshift*/
2009-06-28 13:27:06 +00:00
( binaryfunc ) 0 , /*nb_rshift*/
2011-02-13 10:52:18 +00:00
NULL , /*nb_and*/
NULL , /*nb_xor*/
NULL , /*nb_or*/
NULL , /*nb_int*/
NULL , /*nb_reserved*/
NULL , /*nb_float*/
NULL , /* nb_inplace_add */
NULL , /* nb_inplace_subtract */
NULL , /* nb_inplace_multiply */
NULL , /* nb_inplace_remainder */
NULL , /* nb_inplace_power */
NULL , /* nb_inplace_lshift */
NULL , /* nb_inplace_rshift */
NULL , /* nb_inplace_and */
NULL , /* nb_inplace_xor */
NULL , /* nb_inplace_or */
NULL , /* nb_floor_divide */
NULL , /* nb_true_divide */
NULL , /* nb_inplace_floor_divide */
NULL , /* nb_inplace_true_divide */
NULL , /* nb_index */
2009-06-28 13:27:06 +00:00
} ;
2009-06-18 23:12:29 +00:00
2010-10-13 23:25:08 +00:00
static PyObject * Matrix_getRowSize ( MatrixObject * self , void * UNUSED ( closure ) )
2009-06-18 23:12:29 +00:00
{
2011-02-09 09:20:17 +00:00
return PyLong_FromLong ( ( long ) self - > row_size ) ;
2009-06-18 23:12:29 +00:00
}
2010-10-13 23:25:08 +00:00
static PyObject * Matrix_getColSize ( MatrixObject * self , void * UNUSED ( closure ) )
2009-06-18 23:12:29 +00:00
{
2011-02-09 09:20:17 +00:00
return PyLong_FromLong ( ( long ) self - > col_size ) ;
2009-06-18 23:12:29 +00:00
}
2011-05-18 15:31:00 +00:00
static PyObject * Matrix_median_scale_get ( MatrixObject * self , void * UNUSED ( closure ) )
2010-01-02 22:47:56 +00:00
{
float mat [ 3 ] [ 3 ] ;
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2010-01-02 22:47:56 +00:00
return NULL ;
/*must be 3-4 cols, 3-4 rows, square matrix*/
2011-10-13 01:29:08 +00:00
if ( ( self - > col_size < 3 ) | | ( self - > row_size < 3 ) ) {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_AttributeError ,
2011-09-19 14:29:21 +00:00
" Matrix.median_scale: "
2011-07-14 01:25:05 +00:00
" inappropriate matrix size, 3x3 minimum " ) ;
2010-01-02 22:47:56 +00:00
return NULL ;
}
2011-01-25 16:32:41 +00:00
matrix_as_3x3 ( mat , self ) ;
2010-01-02 22:47:56 +00:00
return PyFloat_FromDouble ( mat3_to_scale ( mat ) ) ;
}
2011-05-18 15:31:00 +00:00
static PyObject * Matrix_is_negative_get ( MatrixObject * self , void * UNUSED ( closure ) )
2010-01-30 13:15:39 +00:00
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2010-01-30 13:15:39 +00:00
return NULL ;
/*must be 3-4 cols, 3-4 rows, square matrix*/
2011-10-13 01:29:08 +00:00
if ( self - > col_size = = 4 & & self - > row_size = = 4 )
2010-02-23 09:39:47 +00:00
return PyBool_FromLong ( is_negative_m4 ( ( float ( * ) [ 4 ] ) self - > contigPtr ) ) ;
2011-10-13 01:29:08 +00:00
else if ( self - > col_size = = 3 & & self - > row_size = = 3 )
2010-02-23 09:39:47 +00:00
return PyBool_FromLong ( is_negative_m3 ( ( float ( * ) [ 3 ] ) self - > contigPtr ) ) ;
2010-01-30 13:15:39 +00:00
else {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_AttributeError ,
2011-09-19 14:29:21 +00:00
" Matrix.is_negative: "
2011-07-14 01:25:05 +00:00
" inappropriate matrix size - expects 3x3 or 4x4 matrix " ) ;
2010-01-30 13:15:39 +00:00
return NULL ;
}
}
2011-05-18 15:31:00 +00:00
static PyObject * Matrix_is_orthogonal_get ( MatrixObject * self , void * UNUSED ( closure ) )
{
2011-10-13 01:29:08 +00:00
if ( BaseMath_ReadCallback ( self ) = = - 1 )
2011-05-18 15:31:00 +00:00
return NULL ;
/*must be 3-4 cols, 3-4 rows, square matrix*/
2011-10-13 01:29:08 +00:00
if ( self - > col_size = = 4 & & self - > row_size = = 4 )
2011-05-18 15:31:00 +00:00
return PyBool_FromLong ( is_orthogonal_m4 ( ( float ( * ) [ 4 ] ) self - > contigPtr ) ) ;
2011-10-13 01:29:08 +00:00
else if ( self - > col_size = = 3 & & self - > row_size = = 3 )
2011-05-18 15:31:00 +00:00
return PyBool_FromLong ( is_orthogonal_m3 ( ( float ( * ) [ 3 ] ) self - > contigPtr ) ) ;
else {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_AttributeError ,
2011-09-19 14:29:21 +00:00
" Matrix.is_orthogonal: "
2011-07-14 01:25:05 +00:00
" inappropriate matrix size - expects 3x3 or 4x4 matrix " ) ;
2011-05-18 15:31:00 +00:00
return NULL ;
}
}
2010-01-30 13:15:39 +00:00
2009-06-18 23:12:29 +00:00
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Matrix_getseters [ ] = {
2010-12-03 17:05:21 +00:00
{ ( char * ) " row_size " , ( getter ) Matrix_getRowSize , ( setter ) NULL , ( char * ) " The row size of the matrix (readonly). \n \n :type: int " , NULL } ,
{ ( char * ) " col_size " , ( getter ) Matrix_getColSize , ( setter ) NULL , ( char * ) " The column size of the matrix (readonly). \n \n :type: int " , NULL } ,
2011-05-18 15:31:00 +00:00
{ ( char * ) " median_scale " , ( getter ) Matrix_median_scale_get , ( setter ) NULL , ( char * ) " The average scale applied to each axis (readonly). \n \n :type: float " , NULL } ,
{ ( char * ) " is_negative " , ( getter ) Matrix_is_negative_get , ( setter ) NULL , ( char * ) " True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly). \n \n :type: bool " , NULL } ,
{ ( char * ) " is_orthogonal " , ( getter ) Matrix_is_orthogonal_get , ( setter ) NULL , ( char * ) " True if this matrix is orthogonal, 3x3 and 4x4 only, (readonly). \n \n :type: bool " , NULL } ,
2010-12-03 17:05:21 +00:00
{ ( char * ) " is_wrapped " , ( getter ) BaseMathObject_getWrapped , ( setter ) NULL , ( char * ) BaseMathObject_Wrapped_doc , NULL } ,
{ ( char * ) " owner " , ( getter ) BaseMathObject_getOwner , ( setter ) NULL , ( char * ) BaseMathObject_Owner_doc , NULL } ,
2011-03-19 11:12:48 +00:00
{ NULL , NULL , NULL , NULL , NULL } /* Sentinel */
2009-06-18 23:12:29 +00:00
} ;
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
/*-----------------------METHOD DEFINITIONS ----------------------*/
static struct PyMethodDef Matrix_methods [ ] = {
2011-02-05 06:14:50 +00:00
/* derived values */
{ " determinant " , ( PyCFunction ) Matrix_determinant , METH_NOARGS , Matrix_determinant_doc } ,
{ " decompose " , ( PyCFunction ) Matrix_decompose , METH_NOARGS , Matrix_decompose_doc } ,
/* in place only */
2011-02-04 03:06:23 +00:00
{ " zero " , ( PyCFunction ) Matrix_zero , METH_NOARGS , Matrix_zero_doc } ,
{ " identity " , ( PyCFunction ) Matrix_identity , METH_NOARGS , Matrix_identity_doc } ,
2011-02-05 06:14:50 +00:00
/* operate on original or copy */
2011-02-04 03:06:23 +00:00
{ " transpose " , ( PyCFunction ) Matrix_transpose , METH_NOARGS , Matrix_transpose_doc } ,
2011-02-05 06:14:50 +00:00
{ " transposed " , ( PyCFunction ) Matrix_transposed , METH_NOARGS , Matrix_transposed_doc } ,
2011-02-04 03:06:23 +00:00
{ " invert " , ( PyCFunction ) Matrix_invert , METH_NOARGS , Matrix_invert_doc } ,
2011-02-05 06:14:50 +00:00
{ " inverted " , ( PyCFunction ) Matrix_inverted , METH_NOARGS , Matrix_inverted_doc } ,
2010-02-23 09:39:47 +00:00
{ " to_3x3 " , ( PyCFunction ) Matrix_to_3x3 , METH_NOARGS , Matrix_to_3x3_doc } ,
2011-02-05 06:14:50 +00:00
// TODO. {"resize_3x3", (PyCFunction) Matrix_resize3x3, METH_NOARGS, Matrix_resize3x3_doc},
{ " to_4x4 " , ( PyCFunction ) Matrix_to_4x4 , METH_NOARGS , Matrix_to_4x4_doc } ,
{ " resize_4x4 " , ( PyCFunction ) Matrix_resize_4x4 , METH_NOARGS , Matrix_resize_4x4_doc } ,
2011-02-05 09:57:02 +00:00
{ " rotate " , ( PyCFunction ) Matrix_rotate , METH_O , Matrix_rotate_doc } ,
2011-02-05 06:14:50 +00:00
/* return converted representation */
2011-02-04 03:06:23 +00:00
{ " to_euler " , ( PyCFunction ) Matrix_to_euler , METH_VARARGS , Matrix_to_euler_doc } ,
2011-02-05 06:14:50 +00:00
{ " to_quaternion " , ( PyCFunction ) Matrix_to_quaternion , METH_NOARGS , Matrix_to_quaternion_doc } ,
{ " to_scale " , ( PyCFunction ) Matrix_to_scale , METH_NOARGS , Matrix_to_scale_doc } ,
{ " to_translation " , ( PyCFunction ) Matrix_to_translation , METH_NOARGS , Matrix_to_translation_doc } ,
/* operation between 2 or more types */
{ " lerp " , ( PyCFunction ) Matrix_lerp , METH_VARARGS , Matrix_lerp_doc } ,
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
{ " copy " , ( PyCFunction ) Matrix_copy , METH_NOARGS , Matrix_copy_doc } ,
{ " __copy__ " , ( PyCFunction ) Matrix_copy , METH_NOARGS , Matrix_copy_doc } ,
2011-02-04 03:06:23 +00:00
2010-08-11 16:40:36 +00:00
/* class methods */
{ " Rotation " , ( PyCFunction ) C_Matrix_Rotation , METH_VARARGS | METH_CLASS , C_Matrix_Rotation_doc } ,
{ " Scale " , ( PyCFunction ) C_Matrix_Scale , METH_VARARGS | METH_CLASS , C_Matrix_Scale_doc } ,
{ " Shear " , ( PyCFunction ) C_Matrix_Shear , METH_VARARGS | METH_CLASS , C_Matrix_Shear_doc } ,
{ " Translation " , ( PyCFunction ) C_Matrix_Translation , METH_O | METH_CLASS , C_Matrix_Translation_doc } ,
{ " OrthoProjection " , ( PyCFunction ) C_Matrix_OrthoProjection , METH_VARARGS | METH_CLASS , C_Matrix_OrthoProjection_doc } ,
Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers in docs)
- Mathutils.MidpointVecs --> vector.lerp(other, fac)
- Mathutils.AngleBetweenVecs --> vector.angle(other)
- Mathutils.ProjectVecs --> vector.project(other)
- Mathutils.DifferenceQuats --> quat.difference(other)
- 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
- Matrix.scalePart --> Matrix.scale_part
- Matrix.translationPart --> Matrix.translation_part
- Matrix.rotationPart --> Matrix.rotation_part
- toMatrix --> to_matrix
- toEuler --> to_euler
- toQuat --> to_quat
- Vector.toTrackQuat --> Vector.to_track_quat
2010-01-25 09:44:04 +00:00
{ NULL , NULL , 0 , NULL }
} ;
2009-06-17 20:33:34 +00:00
/*------------------PY_OBECT DEFINITION--------------------------*/
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( matrix_doc ,
2011-02-04 09:35:20 +00:00
" This object gives access to Matrices in Blender. "
2011-05-24 16:05:51 +00:00
) ;
2009-06-17 20:33:34 +00:00
PyTypeObject matrix_Type = {
PyVarObject_HEAD_INIT ( NULL , 0 )
2011-02-13 10:52:18 +00:00
" mathutils.Matrix " , /*tp_name*/
sizeof ( MatrixObject ) , /*tp_basicsize*/
0 , /*tp_itemsize*/
( destructor ) BaseMathObject_dealloc , /*tp_dealloc*/
NULL , /*tp_print*/
NULL , /*tp_getattr*/
NULL , /*tp_setattr*/
NULL , /*tp_compare*/
( reprfunc ) Matrix_repr , /*tp_repr*/
& Matrix_NumMethods , /*tp_as_number*/
& Matrix_SeqMethods , /*tp_as_sequence*/
& Matrix_AsMapping , /*tp_as_mapping*/
NULL , /*tp_hash*/
NULL , /*tp_call*/
NULL , /*tp_str*/
NULL , /*tp_getattro*/
NULL , /*tp_setattro*/
NULL , /*tp_as_buffer*/
2011-02-24 04:58:51 +00:00
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC , /*tp_flags*/
2011-02-13 10:52:18 +00:00
matrix_doc , /*tp_doc*/
2011-02-24 04:58:51 +00:00
( traverseproc ) BaseMathObject_traverse , //tp_traverse
( inquiry ) BaseMathObject_clear , //tp_clear
2011-02-13 10:52:18 +00:00
( richcmpfunc ) Matrix_richcmpr , /*tp_richcompare*/
0 , /*tp_weaklistoffset*/
NULL , /*tp_iter*/
NULL , /*tp_iternext*/
Matrix_methods , /*tp_methods*/
NULL , /*tp_members*/
Matrix_getseters , /*tp_getset*/
NULL , /*tp_base*/
NULL , /*tp_dict*/
NULL , /*tp_descr_get*/
NULL , /*tp_descr_set*/
0 , /*tp_dictoffset*/
NULL , /*tp_init*/
NULL , /*tp_alloc*/
Matrix_new , /*tp_new*/
NULL , /*tp_free*/
NULL , /*tp_is_gc*/
NULL , /*tp_bases*/
NULL , /*tp_mro*/
NULL , /*tp_cache*/
NULL , /*tp_subclasses*/
NULL , /*tp_weaklist*/
NULL /*tp_del*/
2009-06-17 20:33:34 +00:00
} ;
2011-12-19 05:23:52 +00:00
/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
* ( i . e . it was allocated elsewhere by MEM_mallocN ( ) )
* pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
* ( i . e . it must be created here with PyMEM_malloc ( ) ) */
2011-11-29 20:22:35 +00:00
PyObject * Matrix_CreatePyObject ( float * mat ,
2011-12-19 05:14:09 +00:00
const unsigned short row_size , const unsigned short col_size ,
2011-11-29 20:22:35 +00:00
int type , PyTypeObject * base_type )
2009-06-17 20:33:34 +00:00
{
2011-02-24 05:46:57 +00:00
MatrixObject * self ;
2009-06-17 20:33:34 +00:00
2011-12-19 05:14:09 +00:00
/* matrix objects can be any 2-4row x 2-4col matrix */
if ( row_size < 2 | | row_size > 4 | | col_size < 2 | | col_size > 4 ) {
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_RuntimeError ,
" Matrix(): "
" row and column sizes must be between 2 and 4 " ) ;
2011-02-24 05:46:57 +00:00
return NULL ;
2009-06-17 20:33:34 +00:00
}
2011-02-24 05:46:57 +00:00
self = base_type ? ( MatrixObject * ) base_type - > tp_alloc ( base_type , 0 ) :
( MatrixObject * ) PyObject_GC_New ( MatrixObject , & matrix_Type ) ;
2011-10-13 01:29:08 +00:00
if ( self ) {
2011-12-19 05:14:09 +00:00
self - > row_size = row_size ;
self - > col_size = col_size ;
2011-02-04 03:06:23 +00:00
2011-02-24 05:46:57 +00:00
/* init callbacks as NULL */
self - > cb_user = NULL ;
self - > cb_type = self - > cb_subtype = 0 ;
2011-10-13 01:29:08 +00:00
if ( type = = Py_WRAP ) {
2011-02-24 05:46:57 +00:00
self - > contigPtr = mat ;
self - > wrapped = Py_WRAP ;
2009-06-17 20:33:34 +00:00
}
2011-10-13 01:29:08 +00:00
else if ( type = = Py_NEW ) {
2011-12-19 05:14:09 +00:00
self - > contigPtr = PyMem_Malloc ( row_size * col_size * sizeof ( float ) ) ;
2011-10-13 01:29:08 +00:00
if ( self - > contigPtr = = NULL ) { /*allocation failure*/
2011-07-14 01:25:05 +00:00
PyErr_SetString ( PyExc_MemoryError ,
" Matrix(): "
" problem allocating pointer space " ) ;
2011-02-24 05:46:57 +00:00
return NULL ;
}
2011-12-19 05:14:09 +00:00
2011-10-13 01:29:08 +00:00
if ( mat ) { /*if a float array passed*/
2011-12-19 05:14:09 +00:00
memcpy ( self - > contigPtr , mat , row_size * col_size * sizeof ( float ) ) ;
2009-06-17 20:33:34 +00:00
}
2011-12-19 05:23:52 +00:00
else if ( row_size = = col_size ) {
/* or if no arguments are passed return identity matrix for square matrices */
2011-02-24 05:46:57 +00:00
PyObject * ret_dummy = Matrix_identity ( self ) ;
Py_DECREF ( ret_dummy ) ;
}
2011-12-19 05:14:09 +00:00
else {
2011-12-19 05:23:52 +00:00
/* otherwise zero everything */
2011-12-19 05:14:09 +00:00
memset ( self - > contigPtr , 0 , row_size * col_size * sizeof ( float ) ) ;
}
2011-02-24 05:46:57 +00:00
self - > wrapped = Py_NEW ;
2011-02-24 04:58:51 +00:00
}
2011-02-24 05:46:57 +00:00
else {
2011-07-14 09:54:03 +00:00
Py_FatalError ( " Matrix(): invalid type! " ) ;
2011-02-24 05:46:57 +00:00
return NULL ;
2009-06-17 20:33:34 +00:00
}
2011-02-24 04:58:51 +00:00
}
2011-02-24 05:46:57 +00:00
return ( PyObject * ) self ;
2009-06-17 20:33:34 +00:00
}
2009-06-22 04:26:48 +00:00
2011-11-24 04:45:36 +00:00
PyObject * Matrix_CreatePyObject_cb ( PyObject * cb_user , int rowSize , int colSize , int cb_type , int cb_subtype )
2009-06-23 13:34:45 +00:00
{
2011-11-24 04:45:36 +00:00
MatrixObject * self = ( MatrixObject * ) Matrix_CreatePyObject ( NULL , rowSize , colSize , Py_NEW , NULL ) ;
2011-10-13 01:29:08 +00:00
if ( self ) {
2011-02-24 05:46:57 +00:00
Py_INCREF ( cb_user ) ;
self - > cb_user = cb_user ;
self - > cb_type = ( unsigned char ) cb_type ;
self - > cb_subtype = ( unsigned char ) cb_subtype ;
2011-03-03 06:01:31 +00:00
PyObject_GC_Track ( self ) ;
2009-06-23 13:34:45 +00:00
}
return ( PyObject * ) self ;
}