diff options
author | Stephen Swaney <sswaney@centurytel.net> | 2005-06-13 23:15:02 +0400 |
---|---|---|
committer | Stephen Swaney <sswaney@centurytel.net> | 2005-06-13 23:15:02 +0400 |
commit | 769fa6252d90666768fc13a39eedecee12d8c0df (patch) | |
tree | 0fd2df014f63cf1e0112b7134f05d555f7a943d4 /source/blender/python/api2_2x/CurNurb.c | |
parent | de567cd0cc5532d3a6aa521328230239fa082810 (diff) |
Patch from Martin Poirier.
Misc bpy Curve fixes and updates, includes bugs #1687 and #2637
Diffstat (limited to 'source/blender/python/api2_2x/CurNurb.c')
-rw-r--r-- | source/blender/python/api2_2x/CurNurb.c | 275 |
1 files changed, 255 insertions, 20 deletions
diff --git a/source/blender/python/api2_2x/CurNurb.c b/source/blender/python/api2_2x/CurNurb.c index 7dcbf142737..ce31f348c9f 100644 --- a/source/blender/python/api2_2x/CurNurb.c +++ b/source/blender/python/api2_2x/CurNurb.c @@ -32,6 +32,7 @@ #include "Python.h" #include "DNA_curve_types.h" #include "BKE_curve.h" +#include "BDR_editcurve.h" /* for convertspline */ #include "MEM_guardedalloc.h" #include "gen_utils.h" @@ -52,8 +53,11 @@ static PyObject *CurNurb_getFlagU( BPy_CurNurb * self ); static PyObject *CurNurb_setFlagU( BPy_CurNurb * self, PyObject * args ); static PyObject *CurNurb_getFlagV( BPy_CurNurb * self ); static PyObject *CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args ); +static PyObject *CurNurb_getType( BPy_CurNurb * self ); +static PyObject *CurNurb_setType( BPy_CurNurb * self, PyObject * args ); /* static PyObject* CurNurb_setXXX( BPy_CurNurb* self, PyObject* args ); */ PyObject *CurNurb_getPoint( BPy_CurNurb * self, int index ); +static int CurNurb_setPoint( BPy_CurNurb * self, int index, PyObject * ob ); static int CurNurb_length( PyInstanceObject * inst ); static PyObject *CurNurb_getIter( BPy_CurNurb * self ); static PyObject *CurNurb_iterNext( BPy_CurNurb * self ); @@ -61,6 +65,7 @@ PyObject *CurNurb_append( BPy_CurNurb * self, PyObject * args ); PyObject *CurNurb_pointAtIndex( Nurb * nurb, int index ); static PyObject *CurNurb_isNurb( BPy_CurNurb * self ); static PyObject *CurNurb_isCyclic( BPy_CurNurb * self ); +static PyObject *CurNurb_dump( BPy_CurNurb * self ); char M_CurNurb_doc[] = "CurNurb"; @@ -117,16 +122,21 @@ static PyMethodDef BPy_CurNurb_methods[] = { "( index ) - set flagV and recalculate the knots (0: uniform, 1: endpoints, 2: bezier)"}, {"getFlagV", ( PyCFunction ) CurNurb_getFlagV, METH_NOARGS, "( ) - get flagV of the knots"}, + {"setType", ( PyCFunction ) CurNurb_setType, METH_VARARGS, + "( type ) - change the type of the curve (Poly: 0, Bezier: 1, NURBS: 4)"}, + {"getType", ( PyCFunction ) CurNurb_getType, METH_NOARGS, + "( ) - get the type of the curve (Poly: 0, Bezier: 1, NURBS: 4)"}, {"append", ( PyCFunction ) CurNurb_append, METH_VARARGS, "( point ) - add a new point. arg is BezTriple or list of x,y,z,w floats"}, {"isNurb", ( PyCFunction ) CurNurb_isNurb, METH_NOARGS, "( ) - boolean function tests if this spline is type nurb or bezier"}, {"isCyclic", ( PyCFunction ) CurNurb_isCyclic, METH_NOARGS, "( ) - boolean function tests if this spline is cyclic (closed) or not (open)"}, + {"dump", ( PyCFunction ) CurNurb_dump, METH_NOARGS, + "( ) - dumps Nurb data)"}, {NULL, NULL, 0, NULL} }; - /* * methods for CurNurb as sequece */ @@ -137,7 +147,7 @@ static PySequenceMethods CurNurb_as_sequence = { ( intargfunc ) 0, /* sq_repeat */ ( intargfunc ) CurNurb_getPoint, /* sq_item */ ( intintargfunc ) 0, /* sq_slice */ - 0, /* sq_ass_item */ + ( intobjargproc ) CurNurb_setPoint, /* sq_ass_item */ 0, /* sq_ass_slice */ ( objobjproc ) 0, /* sq_contains */ 0, @@ -261,6 +271,12 @@ static PyObject *CurNurb_getAttr( BPy_CurNurb * self, char *name ) else if( strcmp( name, "flagV" ) == 0 ) attr = CurNurb_getFlagV( self ); + else if( strcmp( name, "type" ) == 0 ) + attr = CurNurb_getType( self ); + + else if( strcmp( name, "__members__" ) == 0 ) + attr = Py_BuildValue( "[s,s,s,s,s]", "mat_index", "points", "flagU", "flagV", "type" ); + if( !attr ) return EXPP_ReturnPyObjError( PyExc_MemoryError, "couldn't create PyObject" ); @@ -292,11 +308,16 @@ static int CurNurb_setAttr( BPy_CurNurb * self, char *name, PyObject * value ) if( strcmp( name, "mat_index" ) == 0 ) error = CurNurb_setMatIndex( self, valtuple ); + else if( strcmp( name, "flagU" ) == 0 ) error = CurNurb_setFlagU( self, valtuple ); + else if( strcmp( name, "flagV" ) == 0 ) error = CurNurb_setFlagV( self, valtuple ); + else if( strcmp( name, "type" ) == 0 ) + error = CurNurb_setType( self, valtuple ); + else { /* error - no match for name */ Py_DECREF( valtuple ); @@ -368,6 +389,45 @@ static PyObject *M_CurNurb_New( PyObject * self, PyObject * args ) } +/* + * Curve.getType + */ +static PyObject *CurNurb_getType( BPy_CurNurb * self ) +{ + /* type is on 3 first bits only */ + return PyInt_FromLong( self->nurb->type & 7 ); +} + +/* + * Curve.setType + * + * Convert the curve using Blender's convertspline fonction + */ +static PyObject *CurNurb_setType( BPy_CurNurb * self, PyObject * args ) +{ + Nurb *nurb = self->nurb; + int type; + + /* parameter type checking */ + if( !PyArg_ParseTuple( args, "i", &type ) ) + return EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected integer argument" ); + + /* parameter value checking */ + if (type != CU_POLY && + type != CU_BEZIER && + type != CU_NURBS) + return EXPP_ReturnPyObjError + ( PyExc_ValueError, "expected integer argument" ); + + /* convert and raise error if impossible */ + if (convertspline(type, nurb)) + return EXPP_ReturnPyObjError + ( PyExc_ValueError, "Conversion Impossible" ); + + return EXPP_incr_ret( Py_None ); +} + /* @@ -384,10 +444,10 @@ PyObject *CurNurb_append( BPy_CurNurb * self, PyObject * args ) } - /* * CurNurb_appendPointToNurb - * this is a non-bpy utility func to add a point to a given nurb + * this is a non-bpy utility func to add a point to a given nurb. + * notice the first arg is Nurb*. */ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args ) @@ -396,19 +456,37 @@ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args ) int i; int size; PyObject *pyOb; - int npoints; + int npoints = nurb->pntsu; /* do we have a list of four floats or a BezTriple? */ if( !PyArg_ParseTuple( args, "O", &pyOb )) - return( EXPP_ReturnPyObjError + return EXPP_ReturnPyObjError ( PyExc_RuntimeError, - "Internal error parsing arguments" ) ); + "Internal error parsing arguments" ); + + - if( BezTriple_CheckPyObject( pyOb ) ) { + /* if curve is empty, adjust type depending on input type */ + if (nurb->bezt==NULL && nurb->bp==NULL) { + if (BezTriple_CheckPyObject( pyOb )) + nurb->type |= CU_BEZIER; + else if (PySequence_Check( pyOb )) + nurb->type |= CU_NURBS; + else + return( EXPP_ReturnPyObjError( PyExc_TypeError, + "Expected a BezTriple or a Sequence of 4 (or 5) floats" ) ); + } + + + + if ((nurb->type & 7)==CU_BEZIER) { BezTriple *tmp; - npoints = nurb->pntsu; + + if( !BezTriple_CheckPyObject( pyOb ) ) + return( EXPP_ReturnPyObjError( PyExc_TypeError, + "Expected a BezTriple\n" ) ); /* printf("\ndbg: got a BezTriple\n"); */ tmp = nurb->bezt; /* save old points */ @@ -430,12 +508,12 @@ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args ) memcpy( nurb->bezt + npoints, BezTriple_FromPyObject( pyOb ), sizeof( BezTriple ) ); - } else if( PySequence_Check( pyOb ) ) { + } + else if( PySequence_Check( pyOb ) ) { size = PySequence_Size( pyOb ); /* printf("\ndbg: got a sequence of size %d\n", size ); */ - if( size == 4 ) { + if( size == 4 || size == 5 ) { BPoint *tmp; - npoints = nurb->pntsu; tmp = nurb->bp; /* save old pts */ @@ -465,6 +543,13 @@ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args ) } + if (size == 5) { + nurb->bp[npoints].alfa = (float)PyFloat_AsDouble( PySequence_GetItem( pyOb, 4 ) ); + } + else { + nurb->bp[npoints].alfa = 0.0f; + } + makeknots( nurb, 1, nurb->flagu >> 1 ); } else if( size == 3 ) { /* 3 xyz coords */ @@ -474,8 +559,8 @@ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args ) } else { /* bail with error */ - return ( EXPP_ReturnPyObjError - ( PyExc_AttributeError, "expected better stuff" ) ); + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected a sequence of 4 (or optionaly 5) floats\n" ); } @@ -727,7 +812,6 @@ static int CurNurb_length( PyInstanceObject * inst ) PyObject *CurNurb_getPoint( BPy_CurNurb * self, int index ) { - PyObject *pyo; Nurb *myNurb; int npoints; @@ -739,19 +823,89 @@ PyObject *CurNurb_getPoint( BPy_CurNurb * self, int index ) /* DELETED: bail if index < 0 */ /* actually, this check is not needed since python treats */ /* negative indices as starting from the right end of a sequence */ + /* + THAT IS WRONG, when passing a negative index, python adjusts it to be positive + BUT it can still overflow in the negatives if the index is too small. + For example, list[-6] when list contains 5 items means index = -1 in here. + (theeth) + */ /* bail if no Nurbs in Curve */ if( npoints == 0 ) return ( EXPP_ReturnPyObjError( PyExc_IndexError, "no points in this CurNurb" ) ); - if( index >= npoints ) /* out of range! */ + /* check index limits */ + if( index >= npoints || index < 0 ) return ( EXPP_ReturnPyObjError( PyExc_IndexError, "index out of range" ) ); - pyo = CurNurb_pointAtIndex( myNurb, index ); + return CurNurb_pointAtIndex( myNurb, index ); +} + +/* + * CurNurb_setPoint + * modifies the Nth point in a Nurb + * this is one of the tp_as_sequence methods, hence the int N argument. + * it is called via the [] = operator, not as a usual instance method. + */ +static int CurNurb_setPoint( BPy_CurNurb * self, int index, PyObject * pyOb ) +{ + Nurb *nurb = self->nurb; + int size; - return ( PyObject * ) pyo; + /* check index limits */ + if( index < 0 || index >= nurb->pntsu ) + return EXPP_ReturnIntError( PyExc_IndexError, + "array assignment index out of range\n" ); + + + /* branch by curve type */ + if ((nurb->type & 7)==CU_BEZIER) { /* BEZIER */ + /* check parameter type */ + if( !BezTriple_CheckPyObject( pyOb ) ) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected a BezTriple\n" ); + + /* copy bezier in array */ + memcpy( nurb->bezt + index, + BezTriple_FromPyObject( pyOb ), sizeof( BezTriple ) ); + + return 0; /* finished correctly */ + } + else { /* NURBS or POLY */ + int i; + + /* check parameter type */ + if (!PySequence_Check( pyOb )) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected a list of 4 (or optionaly 5 if the curve is 3D) floats\n" ); + + size = PySequence_Size( pyOb ); + + /* check sequence size */ + if( size != 4 && size != 5 ) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected a list of 4 (or optionaly 5 if the curve is 3D) floats\n" ); + + /* copy x, y, z, w */ + for( i = 0; i < 4; ++i ) { + float tmpx = + ( float ) PyFloat_AsDouble + ( PySequence_GetItem( pyOb, i ) ); + nurb->bp[index].vec[i] = tmpx; + + } + + if (size == 5) { /* set tilt, if present */ + nurb->bp[index].alfa = (float)PyFloat_AsDouble( PySequence_GetItem( pyOb, 4 ) ); + } + else { /* if not, set default */ + nurb->bp[index].alfa = 0.0f; + } + + return 0; /* finished correctly */ + } } @@ -765,15 +919,23 @@ PyObject *CurNurb_pointAtIndex( Nurb * nurb, int index ) if( nurb->bp ) { /* we have a nurb curve */ int i; - pyo = PyList_New( 4 ); + + /* add Tilt only if curve is 3D */ + if (nurb->flag & CU_3D) + pyo = PyList_New( 5 ); + else + pyo = PyList_New( 4 ); for( i = 0; i < 4; i++ ) { PyList_SetItem( pyo, i, PyFloat_FromDouble( nurb->bp[index]. vec[i] ) ); - } + /* add Tilt only if curve is 3D */ + if (nurb->flag & CU_3D) + PyList_SetItem( pyo, 4, PyFloat_FromDouble( nurb->bp[index].alfa ) ); + } else if( nurb->bezt ) { /* we have a bezier */ /* if an error occurs, we just pass it on */ pyo = BezTriple_CreatePyObject( &( nurb->bezt[index] ) ); @@ -804,3 +966,76 @@ PyObject *CurNurb_Init( void ) M_CurNurb_doc ); return ( submodule ); } + + +/* + dump nurb +*/ + +PyObject *CurNurb_dump( BPy_CurNurb * self ) +{ + BPoint *bp = NULL; + BezTriple *bezt = NULL; + Nurb *nurb = self->nurb; + int npoints = 0; + + if( ! self->nurb ){ /* bail on error */ + printf("\n no Nurb in this CurNurb"); + Py_RETURN_NONE; + } + + printf(" type: %d, mat_nr: %d hide: %d flag: %d", + nurb->type, nurb->mat_nr, nurb->hide, nurb->flag); + printf("\n pntsu: %d, pntsv: %d, resolu: %d resolv: %d", + nurb->pntsu, nurb->pntsv, nurb->resolu, nurb->resolv ); + printf("\n orderu: %d orderv: %d", nurb->orderu, nurb->orderv ); + printf("\n flagu: %d flagv: %d", + nurb->flagu, nurb->flagv ); + + npoints = nurb->pntsu; + + if( nurb->bp ) { /* we have a BPoint */ + int n; + for( n = 0, bp = nurb->bp; + n < npoints; + n++, bp++ ) + { + /* vec[4] */ + printf( "\ncoords[%d]: ", n); + { + int i; + for( i = 0; i < 4; i++){ + printf("%10.3f ", bp->vec[i] ); + } + } + + /* alfa, s[2] */ + printf("\n alpha: %5.2f s: %d %d ", + bp->alfa, bp->s[0], bp->s[1] ); + /* f1, hide */ + printf(" f1 %d hide %d", bp->f1, bp->hide ); + printf("\n"); + } + } + else { /* we have a BezTriple */ + int n; + for( n = 0, bezt = nurb->bezt; + n < npoints; + n++, bezt++ ) + { + int i, j; + printf("\npoint %d: ", n); + for( i = 0; i < 3; i++ ) { + printf("\nvec[%i] ",i ); + for( j = 0; j < 3; j++ ) { + printf(" %5.2f ", bezt->vec[i][j] ); + } + } + + + } + printf("\n"); + } + + Py_RETURN_NONE; +} |