Python API
========== Bugfix #4951: This might be a serious change for python script writers. -- ob.getMatrix('localspace') did not return the correct matrix when the object had a parent; this has been corrected. -- ob.setMatrix(m) did not work predictably (more correctly, in an easy-to- predict manner) when an object had a parent. The method has been changed so that if thee is a parent, it ASSUMES the matrix is "localspace", relative to the parent. The documentation now states this. -- ob.mat and ob.matrix are now read-only attributes, while ob.matrixLocal (which calls Object_setMatrix() ) is now read-write. Ton is not thrilled (is that a fair summary, Ton? ;-) with this method since the ob->obmat is calculated from the loc/rot/size attributes of an object. I'll let him speak on this, but I believe his desire is for this method to be deprecated in the future and replaced with something else.
This commit is contained in:
@@ -677,7 +677,7 @@ Possible arguments (provide as strings):\n\
|
|||||||
"Set the object's rotation according to the specified Euler\n\
|
"Set the object's rotation according to the specified Euler\n\
|
||||||
angles. The argument must be a vector triple"},
|
angles. The argument must be a vector triple"},
|
||||||
{"setMatrix", ( PyCFunction ) Object_SetMatrix, METH_VARARGS,
|
{"setMatrix", ( PyCFunction ) Object_SetMatrix, METH_VARARGS,
|
||||||
"Set and apply a new matrix for the object"},
|
"Set and apply a new local matrix for the object"},
|
||||||
{"setLocation", ( PyCFunction ) Object_setLocation, METH_VARARGS,
|
{"setLocation", ( PyCFunction ) Object_setLocation, METH_VARARGS,
|
||||||
"Set the object's location. The first argument must be a vector\n\
|
"Set the object's location. The first argument must be a vector\n\
|
||||||
triple."},
|
triple."},
|
||||||
@@ -2112,6 +2112,7 @@ static int Object_setEuler( BPy_Object * self, PyObject * args )
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int Object_setMatrix( BPy_Object * self, MatrixObject * mat )
|
static int Object_setMatrix( BPy_Object * self, MatrixObject * mat )
|
||||||
|
#if 0
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
@@ -2146,6 +2147,52 @@ static int Object_setMatrix( BPy_Object * self, MatrixObject * mat )
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
float matrix[4][4]; /* for the result */
|
||||||
|
float invmat[4][4]; /* for the result */
|
||||||
|
|
||||||
|
if( !MatrixObject_Check( mat ) )
|
||||||
|
return EXPP_ReturnIntError( PyExc_TypeError,
|
||||||
|
"expected matrix object as argument" );
|
||||||
|
|
||||||
|
if( mat->rowSize == 4 && mat->colSize == 4 ) {
|
||||||
|
for( x = 0; x < 4; x++ ) {
|
||||||
|
for( y = 0; y < 4; y++ ) {
|
||||||
|
matrix[x][y] = mat->matrix[x][y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if( mat->rowSize == 3 && mat->colSize == 3 ) {
|
||||||
|
for( x = 0; x < 3; x++ ) {
|
||||||
|
for( y = 0; y < 3; y++ ) {
|
||||||
|
matrix[x][y] = mat->matrix[x][y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* if a 3x3 matrix, clear the fourth row/column */
|
||||||
|
for( x = 0; x < 3; x++ )
|
||||||
|
matrix[x][3] = matrix[3][x] = 0.0;
|
||||||
|
matrix[3][3] = 1.0;
|
||||||
|
} else
|
||||||
|
return EXPP_ReturnIntError( PyExc_ValueError,
|
||||||
|
"expected 3x3 or 4x4 matrix" );
|
||||||
|
|
||||||
|
/* localspace matrix is truly relative to the parent, but parameters
|
||||||
|
* stored in object are relative to parentinv matrix. Undo the parent
|
||||||
|
* inverse part before updating obmat and calling apply_obmat() */
|
||||||
|
if( self->object->parent ) {
|
||||||
|
Mat4Invert( invmat, self->object->parentinv );
|
||||||
|
Mat4MulMat4( self->object->obmat, matrix, invmat );
|
||||||
|
} else
|
||||||
|
Mat4CpyMat4( self->object->obmat, matrix );
|
||||||
|
|
||||||
|
apply_obmat( self->object );
|
||||||
|
|
||||||
|
/* since we have messed with object, we need to flag for DAG recalc */
|
||||||
|
self->object->recalc |= OB_RECALC_OB;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4340,7 +4387,7 @@ static PyObject *Object_getMatrixLocal( BPy_Object * self )
|
|||||||
float invmat[4][4]; /* for inverse of parent's matrix */
|
float invmat[4][4]; /* for inverse of parent's matrix */
|
||||||
|
|
||||||
Mat4Invert(invmat, self->object->parent->obmat );
|
Mat4Invert(invmat, self->object->parent->obmat );
|
||||||
Mat4MulMat4(matrix, invmat, self->object->obmat);
|
Mat4MulMat4(matrix, self->object->obmat, invmat);
|
||||||
return newMatrixObject((float*)matrix,4,4,Py_NEW);
|
return newMatrixObject((float*)matrix,4,4,Py_NEW);
|
||||||
} else { /* no parent, so return world space matrix */
|
} else { /* no parent, so return world space matrix */
|
||||||
disable_where_script( 1 );
|
disable_where_script( 1 );
|
||||||
@@ -4697,11 +4744,11 @@ static PyGetSetDef BPy_Object_getseters[] = {
|
|||||||
"Ending frame (for DupliFrames)",
|
"Ending frame (for DupliFrames)",
|
||||||
(void *)EXPP_OBJ_ATTR_DUPEND},
|
(void *)EXPP_OBJ_ATTR_DUPEND},
|
||||||
{"mat",
|
{"mat",
|
||||||
(getter)Object_getMatrixWorld, (setter)Object_setMatrix,
|
(getter)Object_getMatrixWorld, (setter)NULL,
|
||||||
"worldspace matrix: absolute, takes vertex parents, tracking and Ipos into account",
|
"worldspace matrix: absolute, takes vertex parents, tracking and Ipos into account",
|
||||||
NULL},
|
NULL},
|
||||||
{"matrix",
|
{"matrix",
|
||||||
(getter)Object_getMatrixWorld, (setter)Object_setMatrix,
|
(getter)Object_getMatrixWorld, (setter)NULL,
|
||||||
"worldspace matrix: absolute, takes vertex parents, tracking and Ipos into account",
|
"worldspace matrix: absolute, takes vertex parents, tracking and Ipos into account",
|
||||||
NULL},
|
NULL},
|
||||||
{"matrixWorld",
|
{"matrixWorld",
|
||||||
@@ -4709,7 +4756,7 @@ static PyGetSetDef BPy_Object_getseters[] = {
|
|||||||
"worldspace matrix: absolute, takes vertex parents, tracking and Ipos into account",
|
"worldspace matrix: absolute, takes vertex parents, tracking and Ipos into account",
|
||||||
NULL},
|
NULL},
|
||||||
{"matrixLocal",
|
{"matrixLocal",
|
||||||
(getter)Object_getMatrixLocal, (setter)NULL,
|
(getter)Object_getMatrixLocal, (setter)Object_setMatrix,
|
||||||
"localspace matrix: relative to the object's parent",
|
"localspace matrix: relative to the object's parent",
|
||||||
NULL},
|
NULL},
|
||||||
{"matrixOldWorld",
|
{"matrixOldWorld",
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ class Object:
|
|||||||
@ivar matrix: Same as L{mat}. Read-only.
|
@ivar matrix: Same as L{mat}. Read-only.
|
||||||
@type matrix: Matrix
|
@type matrix: Matrix
|
||||||
@ivar matrixLocal: The matrix of the object relative to its parent; if there is no parent,
|
@ivar matrixLocal: The matrix of the object relative to its parent; if there is no parent,
|
||||||
returns the world matrix (L{matrixWorld<Object.Object.matrixWorld>}). Read-only.
|
returns the world matrix (L{matrixWorld<Object.Object.matrixWorld>}).
|
||||||
@type matrixLocal: Matrix
|
@type matrixLocal: Matrix
|
||||||
@ivar matrixOldWorld: Old-type worldspace matrix (prior to Blender 2.34).
|
@ivar matrixOldWorld: Old-type worldspace matrix (prior to Blender 2.34).
|
||||||
Read-only.
|
Read-only.
|
||||||
@@ -1054,15 +1054,23 @@ class Object:
|
|||||||
|
|
||||||
def setMatrix(matrix):
|
def setMatrix(matrix):
|
||||||
"""
|
"""
|
||||||
Sets the object's matrix and updates its transformation.
|
Sets the object's matrix and updates its transformation. If the object
|
||||||
|
has a parent, the matrix transform is relative to the parent.
|
||||||
@type matrix: Py_Matrix 3x3 or 4x4
|
@type matrix: Py_Matrix 3x3 or 4x4
|
||||||
@param matrix: a 3x3 or 4x4 Python matrix. If a 3x3 matrix is given,
|
@param matrix: a 3x3 or 4x4 Python matrix. If a 3x3 matrix is given,
|
||||||
it is extended to a 4x4 matrix.
|
it is extended to a 4x4 matrix.
|
||||||
|
@Note: This method is "bad": when called it changes the location,
|
||||||
|
rotation and size attributes of the object (since Blender uses these
|
||||||
|
values to calculate the object's transformation matrix). Ton is
|
||||||
|
not happy having a method which "pretends" to do a matrix operation.
|
||||||
|
In the future, this method may be replaced with other methods which
|
||||||
|
make it easier for the user to determine the correct loc/rot/size values
|
||||||
|
for necessary for the object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setName(name):
|
def setName(name):
|
||||||
"""
|
"""
|
||||||
Sets the name of the object. A string longer then 20 characters will be shortened.
|
Sets the name of the object. A string longer than 20 characters will be shortened.
|
||||||
@type name: String
|
@type name: String
|
||||||
@param name: The new name for the object.
|
@param name: The new name for the object.
|
||||||
"""
|
"""
|
||||||
@@ -1091,7 +1099,7 @@ class Object:
|
|||||||
if both objects are of the same type.
|
if both objects are of the same type.
|
||||||
@type object: Blender Object
|
@type object: Blender Object
|
||||||
@param object: A Blender Object of the same type.
|
@param object: A Blender Object of the same type.
|
||||||
@note: This function is faster then using L{getData()} and setData()
|
@note: This function is faster than using L{getData()} and setData()
|
||||||
because it skips making a Python object from the object's data.
|
because it skips making a Python object from the object's data.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user