diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h index d42a176b35e..ccdbb8a8324 100644 --- a/source/blender/include/BSE_editipo.h +++ b/source/blender/include/BSE_editipo.h @@ -109,6 +109,7 @@ void select_ipo_bezier_keys(struct Ipo *ipo, int selectmode); void set_ipotype(void); void borderselect_ipo(void); void del_ipo(void); +void del_ipoCurve ( struct IpoCurve * icu ); void free_ipocopybuf(void); void copy_editipo(void); void paste_editipo(void); diff --git a/source/blender/python/api2_2x/Ipo.c b/source/blender/python/api2_2x/Ipo.c index 13f4229df5c..9bcb5fd0073 100644 --- a/source/blender/python/api2_2x/Ipo.c +++ b/source/blender/python/api2_2x/Ipo.c @@ -42,16 +42,12 @@ #include #include #include +#include #include "Ipocurve.h" #include "constant.h" #include "gen_utils.h" - - -/* forward declarations */ -char *GetIpoCurveName( IpoCurve * icu ); - /*****************************************************************************/ /* Python API function prototypes for the Ipo module. */ /*****************************************************************************/ @@ -95,6 +91,7 @@ static PyObject *Ipo_setRctf( BPy_Ipo * self, PyObject * args ); static PyObject *Ipo_getCurve( BPy_Ipo * self, PyObject * args ); static PyObject *Ipo_getCurves( BPy_Ipo * self ); static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * args ); +static PyObject *Ipo_delCurve( BPy_Ipo * self, PyObject * args ); static PyObject *Ipo_getNcurves( BPy_Ipo * self ); static PyObject *Ipo_getNBezPoints( BPy_Ipo * self, PyObject * args ); static PyObject *Ipo_DeleteBezPoints( BPy_Ipo * self, PyObject * args ); @@ -125,6 +122,8 @@ static PyMethodDef BPy_Ipo_methods[] = { "(str) - Change Ipo rctf"}, {"addCurve", ( PyCFunction ) Ipo_addCurve, METH_VARARGS, "() - Return Ipo ncurves"}, + {"delCurve", ( PyCFunction ) Ipo_delCurve, METH_VARARGS, + "() - Delete Ipo curves"}, {"getNcurves", ( PyCFunction ) Ipo_getNcurves, METH_NOARGS, "() - Return Ipo ncurves"}, {"getNBezPoints", ( PyCFunction ) Ipo_getNBezPoints, METH_VARARGS, @@ -1125,6 +1124,42 @@ static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * args ) return IpoCurve_CreatePyObject( icu ); } +/* + Function: Ipo_delCurve + Bpy: Blender.Ipo.delCurve(curtype) + + delete an existing curve from IPO. + example: + ipo = Blender.Ipo.New('Object','ObIpo') + cu = ipo.delCurve('LocX') +*/ + +static PyObject *Ipo_delCurve( BPy_Ipo * self, PyObject * args ) +{ + IpoCurve *icu; + char *strname; + + if( !PyArg_ParseTuple( args, "s", &strname ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, + "string argument" ) ); + + for( icu = self->ipo->curve.first; icu; icu = icu->next ) { + char *str1 = getIpoCurveName( icu ); + if( !strcmp( str1, strname ) ) { + BLI_remlink( &(self->ipo->curve), icu); + if(icu->bezt) MEM_freeN(icu->bezt); + MEM_freeN(icu); + del_ipoCurve ( icu ); + Py_INCREF( Py_None ); + return Py_None; + } + } + + return ( EXPP_ReturnPyObjError + ( PyExc_RuntimeError, "IpoCurve not found" ) ); +} + static PyObject *Ipo_getCurve( BPy_Ipo * self, PyObject * args ) @@ -1137,7 +1172,7 @@ static PyObject *Ipo_getCurve( BPy_Ipo * self, PyObject * args ) ( PyExc_TypeError, "expected string argument" ) ); for( icu = self->ipo->curve.first; icu; icu = icu->next ) { - str1 = GetIpoCurveName( icu ); + str1 = getIpoCurveName( icu ); if( !strcmp( str1, str ) ) return IpoCurve_CreatePyObject( icu ); } @@ -1146,57 +1181,6 @@ static PyObject *Ipo_getCurve( BPy_Ipo * self, PyObject * args ) return Py_None; } -char *GetIpoCurveName( IpoCurve * icu ) -{ - switch ( icu->blocktype ) { - case ID_MA: - { - return getname_mat_ei( icu->adrcode ); - } - case ID_WO: - { - return getname_world_ei( icu->adrcode ); - } - case ID_CA: - { - return getname_cam_ei( icu->adrcode ); - } - case ID_OB: - { - return getname_ob_ei( icu->adrcode, 1 ); /* solve: what if EffX/Y/Z are wanted? */ - } - case ID_TE: - { - return getname_tex_ei( icu->adrcode ); - } - case ID_LA: - { - return getname_la_ei( icu->adrcode ); - } - case ID_AC: - { - return getname_ac_ei( icu->adrcode ); - } - case ID_CU: - { - return getname_cu_ei( icu->adrcode ); - } - case ID_KE: - { - return getname_key_ei( icu->adrcode ); - } - case ID_SEQ: - { - return getname_seq_ei( icu->adrcode ); - } - case IPO_CO: - { - return getname_co_ei( icu->adrcode ); - } - } - return NULL; -} - static PyObject *Ipo_getCurves( BPy_Ipo * self ) { PyObject *attr = PyList_New( 0 ); @@ -1444,9 +1428,7 @@ static PyObject *Ipo_getCurvecurval( BPy_Ipo * self, PyObject * args ) ( PyExc_TypeError, "expected int or string argument" ) ); while( icu ) { - /*char str1[10]; - GetIpoCurveName (icu, str1); */ - str1 = GetIpoCurveName( icu ); + str1 = getIpoCurveName( icu ); if( !strcmp( str1, stringname ) ) break; icu = icu->next; diff --git a/source/blender/python/api2_2x/Ipocurve.c b/source/blender/python/api2_2x/Ipocurve.c index 8bebce34529..67424211171 100644 --- a/source/blender/python/api2_2x/Ipocurve.c +++ b/source/blender/python/api2_2x/Ipocurve.c @@ -80,6 +80,7 @@ static PyObject *IpoCurve_getName( C_IpoCurve * self ); static PyObject *IpoCurve_Recalc( C_IpoCurve * self ); static PyObject *IpoCurve_setName( C_IpoCurve * self, PyObject * args ); static PyObject *IpoCurve_addBezier( C_IpoCurve * self, PyObject * args ); +static PyObject *IpoCurve_delBezier( C_IpoCurve * self, PyObject * args ); static PyObject *IpoCurve_setInterpolation( C_IpoCurve * self, PyObject * args ); static PyObject *IpoCurve_getInterpolation( C_IpoCurve * self ); @@ -105,6 +106,8 @@ static PyMethodDef C_IpoCurve_methods[] = { "(str) - Change IpoCurve Data name"}, {"addBezier", ( PyCFunction ) IpoCurve_addBezier, METH_VARARGS, "(str) - Change IpoCurve Data name"}, + {"delBezier", ( PyCFunction ) IpoCurve_delBezier, METH_VARARGS, + "(int) - delete Bezier point at index"}, {"setInterpolation", ( PyCFunction ) IpoCurve_setInterpolation, METH_VARARGS, "(str) - Change IpoCurve Data name"}, @@ -137,7 +140,7 @@ static PyObject *IpoCurveRepr( C_IpoCurve * self ); /* Python IpoCurve_Type structure definition: */ /*****************************************************************************/ PyTypeObject IpoCurve_Type = { - PyObject_HEAD_INIT( NULL ) /* required macro */ + PyObject_HEAD_INIT( NULL ) /* required macro */ 0, /* ob_size */ "IpoCurve", /* tp_name */ sizeof( C_IpoCurve ), /* tp_basicsize */ @@ -195,7 +198,7 @@ PyObject *IpoCurve_Init( void ) /*****************************************************************************/ static PyObject *M_IpoCurve_Get( PyObject * self, PyObject * args ) { - Py_INCREF(Py_None); + Py_INCREF( Py_None ); return Py_None; } @@ -326,6 +329,72 @@ static PyObject *IpoCurve_addBezier( C_IpoCurve * self, PyObject * args ) return Py_None; } +/* + Function: IpoCurve_delBezier + Bpy: Blender.Ipocurve.delBezier(0) + + Delete an BezTriple from an IPO curve. + example: + ipo = Blender.Ipo.Get('ObIpo') + cu = ipo.getCurve('LocX') + cu.delBezier(0) +*/ + +static PyObject *IpoCurve_delBezier( C_IpoCurve * self, PyObject * args ) +{ + //short MEM_freeN( void *vmemh ); + //void *MEM_mallocN( unsigned int len, char *str ); + int npoints; + int index; + IpoCurve *icu; + BezTriple *tmp; + + if( !PyArg_ParseTuple( args, "i", &index ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected int argument" ) ); + + icu = self->ipocurve; + npoints = icu->totvert - 1; + + /* if index is negative, count from end of list */ + if( index < 0 ) + index += icu->totvert; + /* check range of index */ + if( index < 0 || index > npoints ) + return ( EXPP_ReturnPyObjError + ( PyExc_ValueError, "index outside of list" ) ); + + tmp = icu->bezt; + + /* + if delete empties list, then delete it, otherwise copy the remaining + points to a new list + */ + + if( npoints == 0 ) { + icu->bezt = NULL; + } else { + icu->bezt = + MEM_mallocN( sizeof( BezTriple ) * npoints, "bezt" ); + if( index > 0 ) + memmove( icu->bezt, tmp, index * sizeof( BezTriple ) ); + if( index < npoints ) + memmove( icu->bezt + index, tmp + index + 1, + ( npoints - index ) * sizeof( BezTriple ) ); + } + + /* free old list, adjust vertex count */ + MEM_freeN( tmp ); + icu->totvert--; + + /* call calchandles_* instead of testhandles_* */ + /* I'm not sure this is a complete solution but since we do not */ + /* deal with curve handles right now, it seems ok */ + calchandles_ipocurve( icu ); + + Py_INCREF( Py_None ); + return Py_None; +} static PyObject *IpoCurve_setName( C_IpoCurve * self, PyObject * args ) { @@ -468,10 +537,8 @@ static int IpoCurveSetAttr( C_IpoCurve * self, char *name, PyObject * value ) /*****************************************************************************/ static PyObject *IpoCurveRepr( C_IpoCurve * self ) { - void GetIpoCurveName( IpoCurve * icu, char *s ); - char s[100], s1[100]; - GetIpoCurveName( self->ipocurve, s1 ); - sprintf( s, "IpoCurve %s \n", s1 ); + char s[100]; + sprintf( s, "[IpoCurve \"%s\"]\n", getIpoCurveName( self->ipocurve ) ); return PyString_FromString( s ); } @@ -538,3 +605,39 @@ static PyObject *IpoCurve_evaluate( C_IpoCurve * self, PyObject * args ) return PyFloat_FromDouble( eval ); } + +/* + internal bpy func to get Ipo Curve Name. + We are returning a pointer to string constants so there are + no issues with who owns pointers. +*/ + +char *getIpoCurveName( IpoCurve * icu ) +{ + switch ( icu->blocktype ) { + case ID_MA: + return getname_mat_ei( icu->adrcode ); + case ID_WO: + return getname_world_ei( icu->adrcode ); + case ID_CA: + return getname_cam_ei( icu->adrcode ); + case ID_OB: + return getname_ob_ei( icu->adrcode, 1 ); + /* solve: what if EffX/Y/Z are wanted? */ + case ID_TE: + return getname_tex_ei( icu->adrcode ); + case ID_LA: + return getname_la_ei( icu->adrcode ); + case ID_AC: + return getname_ac_ei( icu->adrcode ); + case ID_CU: + return getname_cu_ei( icu->adrcode ); + case ID_KE: + return getname_key_ei( icu->adrcode ); + case ID_SEQ: + return getname_seq_ei( icu->adrcode ); + case IPO_CO: + return getname_co_ei( icu->adrcode ); + } + return NULL; +} diff --git a/source/blender/python/api2_2x/Ipocurve.h b/source/blender/python/api2_2x/Ipocurve.h index fcfb5fcb551..d26749cbcb4 100644 --- a/source/blender/python/api2_2x/Ipocurve.h +++ b/source/blender/python/api2_2x/Ipocurve.h @@ -50,7 +50,7 @@ PyObject *IpoCurve_Init( void ); PyObject *IpoCurve_CreatePyObject( IpoCurve * ipo ); int IpoCurve_CheckPyObject( PyObject * pyobj ); IpoCurve *IpoCurve_FromPyObject( PyObject * pyobj ); - +char *getIpoCurveName( IpoCurve * icu ); #endif /* EXPP_IPOCURVE_H */ diff --git a/source/blender/python/api2_2x/doc/Ipo.py b/source/blender/python/api2_2x/doc/Ipo.py index cb3da597744..ae11208b4ac 100644 --- a/source/blender/python/api2_2x/doc/Ipo.py +++ b/source/blender/python/api2_2x/doc/Ipo.py @@ -90,7 +90,7 @@ class Ipo: MinkMExp, DistM, ColT, iScale, DistA, MgType, MgH, Lacu, Oct, MgOff, MgGan, NBase1, NBase2. 7. Curve Ipo: Speed. - 8. Key Ipo: Speed, 'Key 1' - 'Key 31'. + 8. Key Ipo: Speed, 'Key 1' - 'Key 63'. 9. Action Ipo: LocX, LocY, LocZ, SizeX, SizeY, SizeZ, QuatX, QuatY, QuatZ, QuatW. 10. Sequence Ipo: Fac. @@ -126,6 +126,14 @@ class Ipo: @return: the corresponding IpoCurve, or None. """ + def removeCurve(curvename): + """ + Remove a existing curve from the IPO object. See addCurve() for possible values for curvename. + @type curvename : string + @rtype: None + @return: None. + """ + def setName(newname): """ Sets the name of the Ipo. @@ -283,6 +291,15 @@ class IpoCurve: @rtype: None @return: None """ + + def delBezier(index): + """ + Deletes a Bezier point from a curve. + @type index: integer + @param index: the index of the Bezier point. Negative values index from the end of the list. + @rtype: None + @return: None + """ def Recalc(): """ @@ -311,7 +328,7 @@ class IpoCurve: MinkMExp, DistM, ColT, iScale, DistA, MgType, MgH, Lacu, Oct, MgOff, MgGan, NBase1, NBase2; 7. Curve Ipo: Speed; - 8. Key Ipo: Speed, 'Key 1' - 'Key 31'; + 8. Key Ipo: Speed, 'Key 1' - 'Key 63'; 9. Action Ipo: LocX, LocY, LocZ, SizeX, SizeY, SizeZ, QuatX, QuatY, QuatZ, QuatW; 10.Sequence Ipo: Fac; diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 19c18f63fa5..f1436d9e5a6 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -3123,8 +3123,25 @@ void borderselect_ipo() } } +/* + * When deleting an IPO curve from Python, check if the IPO is being + * edited and if so clear the pointer to the old curve. + */ +void del_ipoCurve ( IpoCurve * icu ) +{ + int i; + EditIpo *ei= G.sipo->editipo; + if (!ei) return; + for(i=0; itotipo; i++, ei++) { + if ( ei->icu == icu ) { + ei->flag &= ~(IPO_SELECT | IPO_EDIT); + ei->icu= 0; + return; + } + } +} void del_ipo() {