-- Bugfix #3458: keyblock.getData() was getting vertex data from keys

incorrectly, including wrapping curve data as BezTriples.  Needed to
   make a change to beztriple module so we could more easily create a
   "thick" BezTriple object similar to Blender.BezTriple.New().

   The change to BezTriple.h pointed out some dead code in the Ipocurve
   module that could be removed.
This commit is contained in:
Ken Hughes
2005-11-28 05:03:26 +00:00
parent 1745a077ad
commit b2e32f5bd1
5 changed files with 175 additions and 210 deletions

View File

@@ -134,19 +134,44 @@ PyTypeObject BezTriple_Type = {
static PyObject *M_BezTriple_New( PyObject* self, PyObject * args )
{
float numbuf[9];
int status, length;
PyObject* in_args = NULL;
if( !PyArg_ParseTuple( args, "|O", &in_args) ) {
return( EXPP_ReturnPyObjError
( PyExc_AttributeError,
"expected sequence of 3 or 9 floats or nothing"));
}
if( !PyArg_ParseTuple( args, "|O", &in_args) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected sequence of 3 or 9 floats or nothing" );
if( !in_args ) {
in_args = Py_BuildValue( "(fff)", 0.0, 0.0, 0.0 );
}
numbuf[0] = 0.0f; numbuf[1] = 0.0f; numbuf[2] = 0.0f;
numbuf[3] = 0.0f; numbuf[4] = 0.0f; numbuf[5] = 0.0f;
numbuf[6] = 0.0f; numbuf[7] = 0.0f; numbuf[8] = 0.0f;
} else {
if( !PySequence_Check( in_args ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected sequence of 3 or 9 floats or nothing" );
return newBezTriple( in_args );
length = PySequence_Length( in_args );
if( length == 9 )
status = PyArg_ParseTuple( in_args, "fffffffff",
&numbuf[0], &numbuf[1], &numbuf[2],
&numbuf[3], &numbuf[4], &numbuf[5],
&numbuf[6], &numbuf[7], &numbuf[8]);
else if( length == 3 ) {
status = PyArg_ParseTuple( in_args, "fff",
&numbuf[0], &numbuf[1], &numbuf[2]);
numbuf[3] = numbuf[0]; numbuf[6] = numbuf[0];
numbuf[4] = numbuf[1]; numbuf[7] = numbuf[1];
numbuf[5] = numbuf[2]; numbuf[8] = numbuf[2];
} else
return EXPP_ReturnPyObjError( PyExc_TypeError,
"wrong number of points" );
if( !status )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"sequence item not number");
}
return newBezTriple( numbuf );
}
/****************************************************************************
@@ -436,99 +461,35 @@ BezTriple *BezTriple_FromPyObject( PyObject * pyobj )
input args is a sequence - either 3 or 9 floats
*/
PyObject *newBezTriple( PyObject *args)
PyObject *newBezTriple( float *numbuf )
{
BPy_BezTriple *pybez = NULL;
int length;
float numbuf[9];
int status;
/*
check input args:
sequence of nine floats - x,y,z for h1, pt, h2
sequence of 3 floats - x,y,z for pt with zero len handles in AUTO mode
*/
int i, j, num;
PyObject *pyobj = NULL;
BezTriple *bzt = NULL;
/* do we have a sequence of the right length? */
/* create our own beztriple data */
bzt = MEM_callocN( sizeof( BezTriple ), "new bpytriple");
if( ! PySequence_Check( args )) {
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected better stuff"));
}
length = PySequence_Length( args );
if( length != 9 && length != 3 )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"wrong number of points");
{
if (length == 9)
status = PyArg_ParseTuple( args, "fffffffff",
&numbuf[0],
&numbuf[1],
&numbuf[2],
&numbuf[3],
&numbuf[4],
&numbuf[5],
&numbuf[6],
&numbuf[7],
&numbuf[8]);
else if (length == 3)
status = PyArg_ParseTuple( args, "fff",
&numbuf[0],
&numbuf[1],
&numbuf[2]);
else
return EXPP_ReturnPyObjError
( PyExc_AttributeError,
"wrong number of points");
if ( !status )
return EXPP_ReturnPyObjError
( PyExc_AttributeError,
"sequence item not number");
}
/* create our bpy object */
pybez = ( BPy_BezTriple* ) PyObject_New( BPy_BezTriple,
&BezTriple_Type );
if( ! pybez )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"PyObject_New failed");
pybez->beztriple = MEM_callocN( sizeof( BezTriple ), "new bpytriple");
/* check malloc */
if( !bzt )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"MEM_callocN failed");
pybez->own_memory = 1; /* we own it. must free later */
switch( length ) {
case 9: {
int i,j;
int num = 0;
for( i = 0; i < 3; i++ ){
for( j = 0; j < 3; j++){
pybez->beztriple->vec[i][j] = numbuf[num ++];
}
/* copy the data */
num = 0;
for( i = 0; i < 3; i++ ) {
for( j = 0; j < 3; j++) {
bzt->vec[i][j] = numbuf[num++];
}
}
break;
case 3: {
int i;
int num = 0;
/* set h1, pt, and h2 to the same values. */
for( i = 0; i < 3; i++ ) {
pybez->beztriple->vec[0][i] = numbuf[num];
pybez->beztriple->vec[1][i] = numbuf[num];
pybez->beztriple->vec[2][i] = numbuf[num];
++num;
}
}
break;
default:
/* we should not be here! */
break;
}
bzt->h1 = HD_ALIGN;
bzt->h2 = HD_ALIGN;
/* wrap it */
pyobj = BezTriple_CreatePyObject( bzt );
pybez->beztriple->h1 = HD_ALIGN;
pybez->beztriple->h2 = HD_ALIGN;
/* we own it. must free later */
( ( BPy_BezTriple * )pyobj)->own_memory = 1;
return ( PyObject* ) pybez;
return pyobj;
}

View File

@@ -59,7 +59,7 @@ typedef struct {
PyObject *BezTriple_CreatePyObject( BezTriple * bzt );
int BezTriple_CheckPyObject( PyObject * pyobj );
BezTriple *BezTriple_FromPyObject( PyObject * pyobj );
PyObject *newBezTriple( PyObject *args );
PyObject *newBezTriple( float *args );
PyObject *BezTriple_Init( void );
#endif /* EXPP_BEZTRIPLE_H */

View File

@@ -83,7 +83,6 @@ static PyObject *IpoCurve_setExtrapolation( C_IpoCurve * self,
PyObject * args );
static PyObject *IpoCurve_getExtrapolation( C_IpoCurve * self );
static PyObject *IpoCurve_getPoints( C_IpoCurve * self );
static int IpoCurve_setPoints( C_IpoCurve * self, PyObject * value );
static PyObject *IpoCurve_evaluate( C_IpoCurve * self, PyObject * args );
static PyObject *IpoCurve_getDriver( C_IpoCurve * self );
@@ -565,20 +564,6 @@ static PyObject *IpoCurve_getPoints( C_IpoCurve * self )
return list;
}
static int IpoCurve_setPoints( C_IpoCurve * self, PyObject * value )
{
struct BezTriple *bezt;
PyObject *l = PyList_New( 0 );
int i;
for( i = 0; i < self->ipocurve->totvert; i++ ) {
bezt = self->ipocurve->bezt + i;
PyList_Append( l, BezTriple_CreatePyObject( bezt ) );
}
return 0;
}
/*****************************************************************************/
/* Function: IpoCurveRepr */
/* Description: This is a callback function for the C_IpoCurve type. It */
@@ -587,7 +572,7 @@ static int IpoCurve_setPoints( C_IpoCurve * self, PyObject * value )
static PyObject *IpoCurveRepr( C_IpoCurve * self )
{
char s[100];
sprintf( s, "[IpoCurve \"%s\"]\n", getIpoCurveName( self->ipocurve ) );
sprintf( s, "[IpoCurve \"%s\"]", getIpoCurveName( self->ipocurve ) );
return PyString_FromString( s );
}

View File

@@ -25,7 +25,7 @@
*
* This is a new part of Blender.
*
* Contributor(s): Pontus Lidman, Johnny Matthews
* Contributor(s): Pontus Lidman, Johnny Matthews, Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -35,6 +35,7 @@
#include <BLI_blenlib.h>
#include <BKE_global.h>
#include <BKE_main.h>
#include <BKE_curve.h>
#include "Ipocurve.h"
#include "Key.h"
@@ -79,6 +80,8 @@ static PyGetSetDef BPy_Key_getsetters[] = {
"Key value",NULL},
{"ipo",(getter)Key_getIpo, (setter)Key_setIpo,
"ipo linked to key",NULL},
{"blocks",(getter)Key_getBlocks, (setter)NULL,
"blocks linked to the key",NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -97,12 +100,9 @@ static int KeyBlock_setVgroup( BPy_KeyBlock *, PyObject * args );
static int KeyBlock_setSlidermin( BPy_KeyBlock *, PyObject * args );
static int KeyBlock_setSlidermax( BPy_KeyBlock *, PyObject * args );
static struct PyMethodDef KeyBlock_methods[] = {
{ "getData", (PyCFunction) KeyBlock_getData, METH_NOARGS,
"Get keyblock data" },
{ 0, 0, 0, 0 }
};
@@ -117,8 +117,10 @@ static PyGetSetDef BPy_KeyBlock_getsetters[] = {
"Keyblock Slider Maximum",NULL},
{"vgroup",(getter)KeyBlock_getVgroup, (setter)KeyBlock_setVgroup,
"Keyblock VGroup",NULL},
{"data",(getter)KeyBlock_getData, (setter)NULL,
"Keyblock VGroup",NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
};
PyTypeObject Key_Type = {
PyObject_HEAD_INIT( NULL ) 0, /*ob_size */
@@ -197,9 +199,6 @@ PyTypeObject Key_Type = {
NULL
};
PyTypeObject KeyBlock_Type = {
PyObject_HEAD_INIT( NULL ) 0, /*ob_size */
"Blender KeyBlock", /*tp_name */
@@ -277,8 +276,6 @@ PyTypeObject KeyBlock_Type = {
NULL
};
static void Key_dealloc( PyObject * self )
{
PyObject_DEL( self );
@@ -365,7 +362,6 @@ static int Key_setIpo( PyObject * self, PyObject * value )
return 0;
}
static PyObject *Key_getType( PyObject * self )
{
BPy_Key *k = ( BPy_Key * ) self;
@@ -406,7 +402,6 @@ static PyObject *Key_getBlocks( PyObject * self )
return l;
}
static PyObject *Key_getValue( PyObject * self )
{
BPy_Key *k = ( BPy_Key * ) self;
@@ -414,10 +409,7 @@ static PyObject *Key_getValue( PyObject * self )
return PyFloat_FromDouble( k->key->curval );
}
// ------------ Key Block Functions --------------//
/* ------------ Key Block Functions -------------- */
static void KeyBlock_dealloc( PyObject * self )
{
@@ -445,33 +437,33 @@ PyObject *KeyBlock_CreatePyObject( KeyBlock * kb, Key *parentKey )
return ( PyObject * ) keyBlock;
}
static PyObject *KeyBlock_getName( BPy_KeyBlock * self ) {
BPy_KeyBlock *kb = ( BPy_KeyBlock * ) self;
PyObject *name = Py_BuildValue( "s", kb->keyblock->name);
return name;
}
static PyObject *KeyBlock_getPos( BPy_KeyBlock * self ){
BPy_KeyBlock *kb = ( BPy_KeyBlock * ) self;
return PyFloat_FromDouble( kb->keyblock->pos );
}
static PyObject *KeyBlock_getSlidermin( BPy_KeyBlock * self ){
BPy_KeyBlock *kb = ( BPy_KeyBlock * ) self;
return PyFloat_FromDouble( kb->keyblock->slidermin );
}
static PyObject *KeyBlock_getSlidermax( BPy_KeyBlock * self ){
BPy_KeyBlock *kb = ( BPy_KeyBlock * ) self;
return PyFloat_FromDouble( kb->keyblock->slidermax );
}
static PyObject *KeyBlock_getVgroup( BPy_KeyBlock * self ){
BPy_KeyBlock *kb = ( BPy_KeyBlock * ) self;
PyObject *name = Py_BuildValue( "s", kb->keyblock->vgroup);
return name;
}
static int KeyBlock_setName( BPy_KeyBlock * self, PyObject * args ){
char* text = NULL;
BPy_KeyBlock *kb = ( BPy_KeyBlock * ) self;
@@ -508,38 +500,49 @@ static int KeyBlock_setSlidermax( BPy_KeyBlock * self, PyObject * args ){
10.0f );
}
static Curve *find_curve( Key *key )
{
Curve *cu;
if( !key )
return NULL;
for( cu = G.main->curve.first; cu; cu = cu->id.next ) {
if( cu->key == key )
break;
}
return cu;
}
static PyObject *KeyBlock_getData( PyObject * self )
{
/* If this is a mesh key, data is an array of MVert.
If lattice, data is an array of BPoint
If curve, data is an array of BezTriple */
/* If this is a mesh key, data is an array of MVert coords.
If lattice, data is an array of BPoint coords
If curve, data is an array of BezTriple or BPoint */
BPy_KeyBlock *kb = ( BPy_KeyBlock * ) self;
Key *key = kb->key;
char *datap;
int datasize;
int idcode;
int i;
Curve *cu;
Nurb* nu;
PyObject *l;
BPy_KeyBlock *kb = ( BPy_KeyBlock * ) self;
Key *key = kb->key;
PyObject *l = PyList_New( kb->keyblock->totelem );
if( !kb->keyblock->data )
Py_RETURN_NONE;
l = PyList_New( kb->keyblock->totelem );
if( !l )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"PyList_New() failed" );
idcode = GS( key->from->name );
if (!kb->keyblock->data) {
return EXPP_incr_ret( Py_None );
}
switch(idcode) {
case ID_ME:
datasize = sizeof(MVert);
for (i=0, datap = kb->keyblock->data; i<kb->keyblock->totelem; i++) {
BPy_NMVert *mv = PyObject_NEW( BPy_NMVert, &NMVert_Type );
@@ -548,9 +551,9 @@ static PyObject *KeyBlock_getData( PyObject * self )
mv->co[0]=vert->co[0];
mv->co[1]=vert->co[1];
mv->co[2]=vert->co[2];
mv->no[0] = (float)(vert->no[0] / 32767.0);
mv->no[1] = (float)(vert->no[1] / 32767.0);
mv->no[2] = (float)(vert->no[2] / 32767.0);
mv->no[0] = 0.0;
mv->no[1] = 0.0;
mv->no[2] = 0.0;
mv->uvco[0] = mv->uvco[1] = mv->uvco[2] = 0.0;
mv->index = i;
@@ -558,42 +561,60 @@ static PyObject *KeyBlock_getData( PyObject * self )
PyList_SetItem(l, i, ( PyObject * ) mv);
datap += datasize;
datap += kb->key->elemsize;
}
break;
case ID_CU:
datasize = sizeof(BezTriple);
for (i=0, datap = kb->keyblock->data; i<kb->keyblock->totelem; i++) {
BezTriple *bt = (BezTriple *) datap;
PyObject *pybt = BezTriple_CreatePyObject( bt );
PyList_SetItem( l, i, pybt );
datap += datasize;
cu = find_curve ( key );
if( !cu )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"key is no linked to any curve!" );
datasize = count_curveverts(&cu->nurb);
nu = cu->nurb.first;
if( nu->bezt ) {
datasize /= 3;
Py_DECREF (l);
l = PyList_New( datasize );
for( i = 0, datap = kb->keyblock->data; i < datasize;
i++, datap += sizeof(float)*12 ) {
/*
* since the key only stores the control point and not the
* other BezTriple attributes, build a Py_NEW BezTriple
*/
PyObject *pybt = newBezTriple( (float *)datap );
PyList_SetItem( l, i, pybt );
}
} else {
for( i = 0, datap = kb->keyblock->data; i < datasize;
i++, datap += kb->key->elemsize ) {
PyObject *pybt;
float *fp = (float *)datap;
pybt = Py_BuildValue( "[f,f,f]", fp[0],fp[1],fp[2]);
if( !pybt ) {
Py_DECREF( l );
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"Py_BuildValue() failed" );
}
PyList_SetItem( l, i, pybt );
}
}
break;
case ID_LT:
datasize = sizeof(BPoint);
for (i=0, datap = kb->keyblock->data; i<kb->keyblock->totelem; i++) {
/* Lacking a python class for BPoint, use a list of four floats */
BPoint *bp = (BPoint *) datap;
PyObject *bpoint = PyList_New( 4 );
PyList_SetItem( bpoint, 0, PyFloat_FromDouble( bp->vec[0] ) );
PyList_SetItem( bpoint, 1, PyFloat_FromDouble( bp->vec[1] ) );
PyList_SetItem( bpoint, 2, PyFloat_FromDouble( bp->vec[2] ) );
PyList_SetItem( bpoint, 3, PyFloat_FromDouble( bp->vec[3] ) );
PyList_SetItem( l, i, bpoint );
datap += datasize;
for( i = 0, datap = kb->keyblock->data; i < kb->keyblock->totelem;
i++, datap += kb->key->elemsize ) {
/* Lacking a python class for BPoint, use a list of three floats */
PyObject *pybt;
float *fp = (float *)datap;
pybt = Py_BuildValue( "[f,f,f]", fp[0],fp[1],fp[2]);
if( !pybt ) {
Py_DECREF( l );
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"Py_BuildValue() failed" );
}
PyList_SetItem( l, i, pybt );
}
break;
}
@@ -638,7 +659,6 @@ static PyObject *M_Key_Get( PyObject * self, PyObject * args )
}
}
struct PyMethodDef M_Key_methods[] = {
{"Get", M_Key_Get, METH_VARARGS, "Get a key or all key names"},
{NULL, NULL, 0, NULL}
@@ -652,10 +672,8 @@ PyObject *Key_Init( void )
return NULL;
Key_Type.ob_type = &PyType_Type;
//KeyBlock_Type.ob_type = &PyType_Type;
PyType_Ready( &KeyBlock_Type );
submodule =
Py_InitModule3( "Blender.Key", M_Key_methods, "Key module" );

View File

@@ -9,11 +9,12 @@ This module provides access to B{Key} objects in Blender.
@var Types: The type of a key, indicating the type of data in the
data blocks.
- MESH - the key is a Mesh key; data blocks contain
L{NMesh.NMVert} vertices.
- CURVE - the key is a Curve key; data blocks contain
L{Ipo.BezTriple} points.
L{NMVert<NMesh.NMVert>} vertices.
- CURVE - the key is a Curve key; data blocks contains either
L{BezTriples<Ipo.BezTriple>} or points (represented by a list of
3 floating point numbers).
- LATTICE - the key is a Lattice key; data blocks contain
BPoints, each point represented as a list of 4 floating point numbers.
BPoints, each point represented by a list of 3 floating point numbers.
"""
@@ -32,26 +33,25 @@ class Key:
"""
The Key object
==============
An object with keyframes (L{Lattice.Lattice}, L{NMesh.NMesh} or
L{Curve.Curve}) will contain a Key object representing the
An object with keyframes (L{Lattice}, L{NMesh} or
L{Curve}) will contain a Key object representing the
keyframe data.
@ivar ipo: Key Ipo.
Contains the Ipo if one is assigned to the object, B{None} otherwise. Setting to B{None} clears the current Ipo..
@ivar ipo: Key Ipo. Contains the Ipo if one is assigned to the
object, B{None} otherwise. Setting to B{None} clears the current Ipo..
@type ipo: Blender Ipo
@ivar value: The Value of the Key - Read Only
@ivar value: The value of the key. Read-only.
@type value: float
@ivar type: An integer from the L{Types} dictionary
representing the Key type.
representing the Key type. Read-only.
@type type: int
@cvar blocks: A list of KeyBlocks.
@cvar ipo: The L{Ipo.Ipo} object associated with this key.
@ivar blocks: A list of KeyBlocks for the key. Read-only.
@type blocks: Blender KeyBlock.
"""
def getIpo():
"""
Get the L{Ipo.Ipo} object associated with this key.
Get the L{Ipo} object associated with this key.
"""
def getBlocks():
"""
@@ -59,7 +59,6 @@ class Key:
this Key.
"""
class KeyBlock:
"""
The KeyBlock object
@@ -67,34 +66,36 @@ class KeyBlock:
Each Key object has a list of KeyBlocks attached, each KeyBlock
representing a keyframe.
@ivar name: The Name of the Keyblock
Truncated to 32 Characters
@ivar name: The name of the Keyblock. Truncated to 32 characters.
@type name: string
@ivar pos: The position of the keyframe
@ivar pos: The position of the keyframe.
@type pos: float
@ivar slidermin: The minimum value for the action slider
@ivar slidermin: The minimum value for the action slider.
Value is clamped to the range [-10.0,10.0].
@type slidermin: float
@ivar slidermax: The maximum value for the action slider
@ivar slidermax: The maximum value for the action slider.
Value is clamped to the range [-10.0,10.0].
@type slidermax: float
@ivar vgroup: The assigned VGroup for the Key Block
@ivar vgroup: The assigned VGroup for the Key Block.
@type vgroup: string
@cvar data: The data of the KeyBlock (see L{getData}). This
@ivar data: The data of the KeyBlock (see L{getData}). This
attribute is read-only.
@type data: varies
"""
def getData():
"""
Get the data of a KeyBlock, as a list of data items. Each item
will have a different data type depending on the type of this
Key.
Mesh keys have a list of L{NMesh.NMVert} objects in the data
block.
Lattice keys have a list of BPoints in the data block. These
don't have corresponding Python objects yet, so each BPoint is
represented using a list of four floating-point numbers.
Curve keys have a list of L{Ipo.BezTriple} objects in the data
block.
- Mesh keys have a list of L{NMVert<NMesh.NMVert>} objects in the data
block.
- Lattice keys have a list of BPoints in the data block. These
don't have corresponding Python objects yet, so each BPoint is
represented using a list of three floating-point numbers (the
coordinate for each lattice vertex).
- Curve keys return either a list of L{BezTriple<Ipo.BezTriple>}
objects in the data if the curve is a Bezier curve, otherwise it
returns lists of three floats for each NURB or poly coordinate.
"""