svn merge -r 12653:12664 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / python / api2_2x / Curve.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Jacques Guignot, Stephen Swaney
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include "Curve.h" /*This must come first*/
34
35 #include "BLI_blenlib.h"
36 #include "BKE_main.h"
37 #include "BKE_displist.h"
38 #include "BKE_global.h"
39 #include "BKE_library.h"
40 #include "BKE_curve.h"
41 #include "BKE_material.h"
42 #include "MEM_guardedalloc.h"   /* because we wil be mallocing memory */
43 #include "CurNurb.h"
44 #include "SurfNurb.h"
45 #include "Material.h"
46 #include "Object.h"
47 #include "Key.h"
48 #include "gen_utils.h"
49 #include "gen_library.h"
50 #include "mydevice.h"
51
52
53 /*****************************************************************************/
54 /* The following string definitions are used for documentation strings.      */
55 /* In Python these will be written to the console when doing a               */
56 /*  Blender.Curve.__doc__                                                    */
57 /*****************************************************************************/
58
59 char M_Curve_doc[] = "The Blender Curve module\n\n\
60 This module provides access to **Curve Data** in Blender.\n\
61 Functions :\n\
62         New(opt name) : creates a new curve object with the given name (optional)\n\
63         Get(name) : retreives a curve  with the given name (mandatory)\n\
64         get(name) : same as Get. Kept for compatibility reasons";
65 char M_Curve_New_doc[] = "";
66 char M_Curve_Get_doc[] = "xxx";
67
68
69
70 /*****************************************************************************/
71 /*  Python API function prototypes for the Curve module.                     */
72 /*****************************************************************************/
73 static PyObject *M_Curve_New( PyObject * self, PyObject * args );
74 static PyObject *M_Curve_Get( PyObject * self, PyObject * args );
75
76
77 /*****************************************************************************/
78 /*  Python BPy_Curve instance methods declarations:                          */
79 /*****************************************************************************/
80
81 static PyObject *Curve_getPathLen( BPy_Curve * self );
82 static PyObject *Curve_setPathLen( BPy_Curve * self, PyObject * args );
83 static PyObject *Curve_getTotcol( BPy_Curve * self );
84 static PyObject *Curve_setTotcol( BPy_Curve * self, PyObject * args );
85 #if 0
86 PyObject *Curve_getResolu( BPy_Curve * self );
87 PyObject *Curve_setResolu( BPy_Curve * self, PyObject * args );
88 PyObject *Curve_getResolv( BPy_Curve * self );
89 PyObject *Curve_setResolv( BPy_Curve * self, PyObject * args );
90 PyObject *Curve_getWidth( BPy_Curve * self );
91 PyObject *Curve_setWidth( BPy_Curve * self, PyObject * args );
92 PyObject *Curve_getExt1( BPy_Curve * self );
93 PyObject *Curve_setExt1( BPy_Curve * self, PyObject * args );
94 PyObject *Curve_getExt2( BPy_Curve * self );
95 PyObject *Curve_setExt2( BPy_Curve * self, PyObject * args );
96 #endif
97 static PyObject *Curve_getControlPoint( BPy_Curve * self, PyObject * args );
98 static PyObject *Curve_setControlPoint( BPy_Curve * self, PyObject * args );
99 static PyObject *Curve_getLoc( BPy_Curve * self );
100 static PyObject *Curve_setLoc( BPy_Curve * self, PyObject * args );
101 static PyObject *Curve_getRot( BPy_Curve * self );
102 static PyObject *Curve_setRot( BPy_Curve * self, PyObject * args );
103 static PyObject *Curve_getSize( BPy_Curve * self );
104 static PyObject *Curve_setSize( BPy_Curve * self, PyObject * args );
105 static PyObject *Curve_getNumCurves( BPy_Curve * self );
106 static PyObject *Curve_getKey( BPy_Curve * self );
107 static PyObject *Curve_isNurb( BPy_Curve * self, PyObject * args );
108 static PyObject *Curve_isCyclic( BPy_Curve * self, PyObject * args);
109 static PyObject *Curve_getNumPoints( BPy_Curve * self, PyObject * args );
110
111 static PyObject *Curve_appendPoint( BPy_Curve * self, PyObject * args );
112 static PyObject *Curve_appendNurb( BPy_Curve * self, PyObject * args );
113
114 static PyObject *Curve_getMaterials( BPy_Curve * self );
115
116 static PyObject *Curve_getBevOb( BPy_Curve * self );
117 static PyObject *Curve_setBevOb( BPy_Curve * self, PyObject * args );
118
119 static PyObject *Curve_getTaperOb( BPy_Curve * self );
120 static PyObject *Curve_setTaperOb( BPy_Curve * self, PyObject * args );
121 static PyObject *Curve_copy( BPy_Curve * self );
122
123 static PyObject *Curve_getIter( BPy_Curve * self );
124 static PyObject *Curve_iterNext( BPy_Curve * self );
125
126 PyObject *Curve_getNurb( BPy_Curve * self, int n );
127 static int Curve_setNurb( BPy_Curve * self, int n, PyObject * value );
128 static int Curve_length( PyInstanceObject * inst );
129
130
131 struct chartrans *text_to_curve( Object * ob, int mode );
132 /*****************************************************************************/
133 /* Python BPy_Curve methods:                                                 */
134 /* gives access to                                                           */
135 /* name, pathlen totcol flag bevresol                                        */
136 /* resolu resolv width ext1 ext2                                             */
137 /* controlpoint loc rot size                                                 */
138 /* numpts                                                                    */
139 /*****************************************************************************/
140
141
142 PyObject *Curve_getName( BPy_Curve * self )
143 {
144         return PyString_FromString( self->curve->id.name + 2 );
145 }
146
147 static int Curve_newsetName( BPy_Curve * self, PyObject * args )
148 {
149         char *name;
150
151         name = PyString_AsString( args );
152         if( !name )
153                 return EXPP_ReturnIntError( PyExc_TypeError,
154                                               "expected string argument" );
155
156         rename_id( &self->curve->id, name );    /* proper way in Blender */
157         Curve_update( self );
158
159         return 0;
160 }
161
162 static PyObject *Curve_getPathLen( BPy_Curve * self )
163 {
164         return PyInt_FromLong( ( long ) self->curve->pathlen );
165 }
166
167
168 static int Curve_newsetPathLen( BPy_Curve * self, PyObject * args )
169 {
170         PyObject *num;
171
172         if( !PyNumber_Check( args ) )
173                 return EXPP_ReturnIntError( PyExc_TypeError,
174                                 "expected int argument" );
175
176         num = PyNumber_Int( args );
177         self->curve->pathlen = (short)PyInt_AS_LONG( num );
178         Py_DECREF( num );
179
180         return 0;
181 }
182
183 static PyObject *Curve_getTotcol( BPy_Curve * self )
184 {
185         return PyInt_FromLong( ( long ) self->curve->totcol );
186 }
187
188
189 PyObject *Curve_getMode( BPy_Curve * self )
190 {
191         return PyInt_FromLong( ( long ) self->curve->flag );
192 }
193
194
195 static int Curve_newsetMode( BPy_Curve * self, PyObject * args )
196 {
197         PyObject *num;
198
199         if( !PyNumber_Check( args ) )
200                 return EXPP_ReturnIntError( PyExc_TypeError,
201                                 "expected int argument" );
202
203         num = PyNumber_Int( args );
204         self->curve->flag = (short)PyInt_AS_LONG( num );
205         Py_DECREF( num );
206
207         return 0;
208 }
209
210 PyObject *Curve_getBevresol( BPy_Curve * self )
211 {
212         return PyInt_FromLong( ( long ) self->curve->bevresol );
213 }
214
215 static int Curve_newsetBevresol( BPy_Curve * self, PyObject * args )
216 {
217         short value;
218         PyObject *num;
219
220         if( !PyNumber_Check( args ) )
221                 return EXPP_ReturnIntError( PyExc_TypeError,
222                                 "expected int argument" );
223
224         num = PyNumber_Int( args );
225         value = (short)PyInt_AS_LONG( num );
226         Py_DECREF( num );
227
228         if( value > 10 || value < 0 )
229                 return EXPP_ReturnIntError( PyExc_ValueError,
230                                 "acceptable values are between 0 and 10" );
231
232         self->curve->bevresol = value;
233         return 0;
234 }
235
236
237 PyObject *Curve_getResolu( BPy_Curve * self )
238 {
239         return PyInt_FromLong( ( long ) self->curve->resolu );
240 }
241
242
243 static int Curve_newsetResolu( BPy_Curve * self, PyObject * args )
244 {
245         short value;
246         Nurb *nu;
247         PyObject *num;
248
249         if( !PyNumber_Check( args ) )
250                 return EXPP_ReturnIntError( PyExc_TypeError,
251                                 "expected int argument" );
252
253         num = PyNumber_Int( args );
254         value = (short)PyInt_AS_LONG( num );
255         Py_DECREF( num );
256
257         if( value > 128 || value < 1 )
258                 return EXPP_ReturnIntError( PyExc_ValueError,
259                                 "acceptable values are between 1 and 128" );
260
261         self->curve->resolu = value;
262         /* propagate the change through all the curves */
263         for( nu = self->curve->nurb.first; nu; nu = nu->next )
264                 nu->resolu = value;
265
266         return 0;
267 }
268
269 PyObject *Curve_getResolv( BPy_Curve * self )
270 {
271         return PyInt_FromLong( ( long ) self->curve->resolv );
272 }
273
274 static int Curve_newsetResolv( BPy_Curve * self, PyObject * args )
275 {
276         short value;
277         PyObject *num;
278
279         if( !PyNumber_Check( args ) )
280                 return EXPP_ReturnIntError( PyExc_TypeError,
281                                 "expected int argument" );
282
283         num = PyNumber_Int( args );
284         value = (short)PyInt_AS_LONG( num );
285         Py_DECREF( num );
286
287         if(value > 128 || value < 1)
288                 return EXPP_ReturnIntError( PyExc_ValueError,
289                         "acceptable values are between 1 and 128" );
290         self->curve->resolv = value;
291
292         return 0;
293 }
294
295 PyObject *Curve_getWidth( BPy_Curve * self )
296 {
297         return PyFloat_FromDouble( ( double ) self->curve->width );
298 }
299
300
301 static int Curve_newsetWidth( BPy_Curve * self, PyObject * args )
302 {
303         float value;
304         PyObject *num;
305
306         if( !PyNumber_Check( args ) )
307                 return EXPP_ReturnIntError( PyExc_TypeError,
308                                 "expected float argument" );
309
310         num = PyNumber_Float( args );
311         value = (float)PyFloat_AS_DOUBLE( num );
312         Py_DECREF( num );
313
314         if(value > 2.0f || value < 0.0f)
315                 return EXPP_ReturnIntError( PyExc_ValueError,
316                                 "acceptable values are between 2.0 and 0.0" );
317         self->curve->width = value;
318
319         return 0;
320 }
321
322
323 PyObject *Curve_getExt1( BPy_Curve * self )
324 {
325         return PyFloat_FromDouble( ( double ) self->curve->ext1 );
326 }
327
328
329 static int Curve_newsetExt1( BPy_Curve * self, PyObject * args )
330 {
331         float value;
332         PyObject *num;
333
334         if( !PyNumber_Check( args ) )
335                 return EXPP_ReturnIntError( PyExc_TypeError,
336                                 "expected float argument" );
337
338         num = PyNumber_Float( args );
339         value = (float)PyFloat_AS_DOUBLE( num );
340         Py_DECREF( num );
341
342         if(value > 100.0f || value < 0.0f)
343                 return EXPP_ReturnIntError( PyExc_ValueError,
344                                 "acceptable values are between 0.0 and 100.0" );
345         self->curve->ext1 = value;
346
347         return 0;
348 }
349
350 PyObject *Curve_getExt2( BPy_Curve * self )
351 {
352         return PyFloat_FromDouble( ( double ) self->curve->ext2 );
353 }
354
355
356 static int Curve_newsetExt2( BPy_Curve * self, PyObject * args )
357 {
358         float value;
359         PyObject *num;
360
361         if( !PyNumber_Check( args ) )
362                 return EXPP_ReturnIntError( PyExc_TypeError,
363                                 "expected float argument" );
364
365         num = PyNumber_Float( args );
366         value = (float)PyFloat_AS_DOUBLE( num );
367         Py_DECREF( num );
368
369         if(value > 2.0f || value < 0.0f)
370                 return EXPP_ReturnIntError( PyExc_ValueError,
371                                 "acceptable values are between 0.0 and 2.0" );
372         self->curve->ext2 = value;
373
374         return 0;
375 }
376
377 /*
378  * Curve_setControlPoint
379  * this function sets an EXISTING control point.
380  * it does NOT add a new one.
381  */
382
383 static PyObject *Curve_setControlPoint( BPy_Curve * self, PyObject * args )
384 {
385         PyObject *listargs = 0;
386         Nurb *ptrnurb = self->curve->nurb.first;
387         int numcourbe = 0, numpoint = 0, i, j;
388
389         if( !ptrnurb )
390                 Py_RETURN_NONE;
391
392         if( ptrnurb->bp )
393                 if( !PyArg_ParseTuple
394                     ( args, "iiO", &numcourbe, &numpoint, &listargs ) )
395                         return ( EXPP_ReturnPyObjError
396                                  ( PyExc_TypeError,
397                                    "expected int, int, list arguments" ) );
398         if( ptrnurb->bezt )
399                 if( !PyArg_ParseTuple
400                     ( args, "iiO", &numcourbe, &numpoint, &listargs ) )
401                         return ( EXPP_ReturnPyObjError
402                                  ( PyExc_TypeError,
403                                    "expected int, int, list arguments" ) );
404
405         for( i = 0; i < numcourbe; i++ )
406                 ptrnurb = ptrnurb->next;
407
408         if( ptrnurb->bp )
409                 for( i = 0; i < 4; i++ )
410                         ptrnurb->bp[numpoint].vec[i] =
411                                 (float)PyFloat_AsDouble( PyList_GetItem ( listargs, i ) );
412
413         if( ptrnurb->bezt )
414                 for( i = 0; i < 3; i++ )
415                         for( j = 0; j < 3; j++ )
416                                 ptrnurb->bezt[numpoint].vec[i][j] =
417                                         (float)PyFloat_AsDouble( PyList_GetItem
418                                                           ( listargs,
419                                                             i * 3 + j ) );
420
421         Py_RETURN_NONE;
422 }
423
424
425 static PyObject *Curve_getControlPoint( BPy_Curve * self, PyObject * args )
426 {
427         PyObject *liste;
428         PyObject *item;
429
430         Nurb *ptrnurb;
431         int i, j;
432         /* input args: requested curve and point number on curve */
433         int numcourbe, numpoint;
434
435         if( !PyArg_ParseTuple( args, "ii", &numcourbe, &numpoint ) )
436                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
437                                         "expected int int arguments" ) );
438         if( ( numcourbe < 0 ) || ( numpoint < 0 ) )
439                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
440                                                 "arguments must be non-negative" ) );
441
442         /* if no nurbs in this curve obj */
443         if( !self->curve->nurb.first )
444                 return PyList_New( 0 );
445
446         /* walk the list of nurbs to find requested numcourbe */
447         ptrnurb = self->curve->nurb.first;
448         for( i = 0; i < numcourbe; i++ ) {
449                 ptrnurb = ptrnurb->next;
450                 if( !ptrnurb )  /* if zero, we ran just ran out of curves */
451                         return ( EXPP_ReturnPyObjError( PyExc_ValueError,
452                                                         "curve index out of range" ) );
453         }
454
455         /* check numpoint param against pntsu */
456         if( numpoint >= ptrnurb->pntsu )
457                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
458                                                 "point index out of range" ) );
459         
460         liste = PyList_New( 0 );
461         if( ptrnurb->bp ) {     /* if we are a nurb curve, you get 4 values */
462                 for( i = 0; i < 4; i++ ) {
463                         item = PyFloat_FromDouble( ptrnurb->bp[numpoint].vec[i] );
464                         PyList_Append( liste, item );
465                         Py_DECREF(item);
466                 }
467         } else if( ptrnurb->bezt ) {    /* if we are a bezier, you get 9 values */
468                 for( i = 0; i < 3; i++ )
469                         for( j = 0; j < 3; j++ ) {
470                                 item = PyFloat_FromDouble( ptrnurb->bezt[numpoint].vec[i][j] );
471                                 PyList_Append( liste, item );
472                                 Py_DECREF(item);
473                         }
474         }
475
476         return liste;
477 }
478
479 static PyObject *Curve_getLoc( BPy_Curve * self )
480 {
481         return Py_BuildValue( "[f,f,f]", self->curve->loc[0],
482                                 self->curve->loc[1], self->curve->loc[2] );
483 }
484
485 static int Curve_newsetLoc( BPy_Curve * self, PyObject * args )
486 {
487         float loc[3];
488         int i;
489
490         if( ( !PyList_Check( args ) && !PyTuple_Check( args ) ) ||
491                         PySequence_Size( args ) != 3 ) {
492 TypeError:
493                 return EXPP_ReturnIntError( PyExc_TypeError,
494                                 "expected a sequence of three floats" );
495         }
496
497         for( i = 0; i < 3; i++ ) {
498                 PyObject *item = PySequence_GetItem( args, i );
499                 PyObject *num = PyNumber_Float( item );
500                 Py_DECREF( item );
501                 if( !num )
502                         goto TypeError;
503                 loc[i] = PyFloat_AS_DOUBLE( num );
504                 Py_DECREF( num );
505         }
506         memcpy( self->curve->loc, loc, sizeof( loc ) );
507
508         return 0;
509 }
510
511 static PyObject *Curve_getRot( BPy_Curve * self )
512 {
513         return Py_BuildValue( "[f,f,f]", self->curve->rot[0],
514                                 self->curve->rot[1], self->curve->rot[2] );
515 }
516
517 static int Curve_newsetRot( BPy_Curve * self, PyObject * args )
518 {
519         float rot[3];
520         int i;
521
522         if( ( !PyList_Check( args ) && !PyTuple_Check( args ) ) ||
523                         PySequence_Size( args ) != 3 ) {
524 TypeError:
525                 return EXPP_ReturnIntError( PyExc_TypeError,
526                                 "expected a sequence of three floats" );
527         }
528
529         for( i = 0; i < 3; i++ ) {
530                 PyObject *item = PySequence_GetItem( args, i );
531                 PyObject *num = PyNumber_Float( item );
532                 Py_DECREF( item );
533                 if( !num )
534                         goto TypeError;
535                 rot[i] = PyFloat_AS_DOUBLE( num );
536                 Py_DECREF( num );
537         }
538         memcpy( self->curve->rot, rot, sizeof( rot ) );
539
540         return 0;
541 }
542
543 static PyObject *Curve_getSize( BPy_Curve * self )
544 {
545         return Py_BuildValue( "[f,f,f]", self->curve->size[0],
546                                 self->curve->size[1], self->curve->size[2] );
547 }
548
549 static int Curve_newsetSize( BPy_Curve * self, PyObject * args )
550 {
551         float size[3];
552         int i;
553
554         if( ( !PyList_Check( args ) && !PyTuple_Check( args ) ) ||
555                         PySequence_Size( args ) != 3 ) {
556 TypeError:
557                 return EXPP_ReturnIntError( PyExc_TypeError,
558                                 "expected a sequence of three floats" );
559         }
560
561         for( i = 0; i < 3; i++ ) {
562                 PyObject *item = PySequence_GetItem( args, i );
563                 PyObject *num = PyNumber_Float( item );
564                 Py_DECREF( item );
565                 if( !num )
566                         goto TypeError;
567                 size[i] = PyFloat_AS_DOUBLE( num );
568                 Py_DECREF( num );
569         }
570         memcpy( self->curve->size, size, sizeof( size ) );
571
572         return 0;
573 }
574
575 /*
576  * Count the number of splines in a Curve Object
577  * int getNumCurves()
578  */
579
580 static PyObject *Curve_getNumCurves( BPy_Curve * self )
581 {
582         Nurb *ptrnurb;
583         PyObject *ret_val;
584         int num_curves = 0;     /* start with no splines */
585
586         /* get curve */
587         ptrnurb = self->curve->nurb.first;
588         if( ptrnurb ) {         /* we have some nurbs in this curve */
589                 for(;;) {
590                         ++num_curves;
591                         ptrnurb = ptrnurb->next;
592                         if( !ptrnurb )  /* no more curves */
593                                 break;
594                 }
595         }
596
597         ret_val = PyInt_FromLong( ( long ) num_curves );
598
599         if( ret_val )
600                 return ret_val;
601
602         /* oops! */
603         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
604                                         "couldn't get number of curves" );
605 }
606
607 /*
608  * get the key object linked to this curve
609  */
610
611 static PyObject *Curve_getKey( BPy_Curve * self )
612 {
613         PyObject *keyObj;
614
615         if (self->curve->key)
616                 keyObj = Key_CreatePyObject(self->curve->key);
617         else keyObj = EXPP_incr_ret(Py_None);
618
619         return keyObj;
620 }
621
622 /*
623  * count the number of points in a given spline
624  * int getNumPoints( curve_num=0 )
625  *
626  */
627
628 static PyObject *Curve_getNumPoints( BPy_Curve * self, PyObject * args )
629 {
630         Nurb *ptrnurb;
631         PyObject *ret_val;
632         int curve_num = 0;      /* default spline number */
633         int i;
634
635         /* parse input arg */
636         if( !PyArg_ParseTuple( args, "|i", &curve_num ) )
637                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
638                                                 "expected int argument" ) );
639
640         /* check arg - must be non-negative */
641         if( curve_num < 0 )
642                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
643                                                 "argument must be non-negative" ) );
644
645
646         /* walk the list of curves looking for our curve */
647         ptrnurb = self->curve->nurb.first;
648         if( !ptrnurb ) {        /* no splines in this Curve */
649                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
650                                                 "no splines in this Curve" ) );
651         }
652
653         for( i = 0; i < curve_num; i++ ) {
654                 ptrnurb = ptrnurb->next;
655                 if( !ptrnurb )  /* if zero, we ran just ran out of curves */
656                         return ( EXPP_ReturnPyObjError( PyExc_ValueError,
657                                                         "curve index out of range" ) );
658         }
659
660         /* pntsu is the number of points in curve */
661         ret_val = PyInt_FromLong( ( long ) ptrnurb->pntsu );
662
663         if( ret_val )
664                 return ret_val;
665
666         /* oops! */
667         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
668                         "couldn't get number of points for curve" );
669 }
670
671 /*
672  * Test whether a given spline of a Curve is a nurb
673  *  as opposed to a bezier
674  * int isNurb( curve_num=0 )
675  */
676
677 static PyObject *Curve_isNurb( BPy_Curve * self, PyObject * args )
678 {
679         int curve_num = 0;      /* default value */
680         int is_nurb;
681         Nurb *ptrnurb;
682         PyObject *ret_val;
683         int i;
684
685         /* parse and check input args */
686         if( !PyArg_ParseTuple( args, "|i", &curve_num ) ) {
687                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
688                                                 "expected int argument" ) );
689         }
690         if( curve_num < 0 ) {
691                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
692                                                 "curve number must be non-negative" ) );
693         }
694
695         ptrnurb = self->curve->nurb.first;
696
697         if( !ptrnurb )          /* no splines in this curve */
698                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
699                                                 "no splines in this Curve" ) );
700
701         for( i = 0; i < curve_num; i++ ) {
702                 ptrnurb = ptrnurb->next;
703                 if( !ptrnurb )  /* if zero, we ran just ran out of curves */
704                         return ( EXPP_ReturnPyObjError( PyExc_ValueError,
705                                                         "curve index out of range" ) );
706         }
707
708         /* right now, there are only two curve types, nurb and bezier. */
709         is_nurb = ptrnurb->bp ? 1 : 0;
710
711         ret_val = PyInt_FromLong( ( long ) is_nurb );
712         if( ret_val )
713                 return ret_val;
714
715         /* oops */
716         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
717                                         "couldn't get curve type" ) );
718 }
719
720 /* trying to make a check for closedness (cyclic), following on isNurb (above) 
721    copy-pasting done by antont@kyperjokki.fi */
722
723 static PyObject *Curve_isCyclic( BPy_Curve * self, PyObject * args )
724 {
725         int curve_num = 0;      /* default value */
726         /* unused:*/
727         /* int is_cyclic;
728          * PyObject *ret_val;*/
729         Nurb *ptrnurb;
730         int i;
731
732         /* parse and check input args */
733         if( !PyArg_ParseTuple( args, "|i", &curve_num ) ) {
734                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
735                                                 "expected int argument" ) );
736         }
737         if( curve_num < 0 ) {
738                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
739                                                 "curve number must be non-negative" ) );
740         }
741
742         ptrnurb = self->curve->nurb.first;
743
744         if( !ptrnurb )          /* no splines in this curve */
745                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
746                                                 "no splines in this Curve" ) );
747
748         for( i = 0; i < curve_num; i++ ) {
749                 ptrnurb = ptrnurb->next;
750                 if( !ptrnurb )  /* if zero, we ran just ran out of curves */
751                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
752                                                         "curve index out of range" ) );
753         }
754
755         if(  ptrnurb->flagu & CU_CYCLIC ){
756                 return EXPP_incr_ret_True();
757         } else {
758                 return EXPP_incr_ret_False();
759         }
760 }
761
762
763 /*
764  * Curve_appendPoint( numcurve, new_point )
765  * append a new point to indicated spline
766  */
767
768 static PyObject *Curve_appendPoint( BPy_Curve * self, PyObject * args )
769 {
770         int i;
771         int nurb_num;           /* index of curve we append to */
772         PyObject *coord_args;   /* coords for new point */
773         Nurb *nurb = self->curve->nurb.first;   /* first nurb in Curve */
774
775 /* fixme - need to malloc new Nurb */
776         if( !nurb )
777                 return ( EXPP_ReturnPyObjError
778                          ( PyExc_AttributeError, "no nurbs in this Curve" ) );
779
780         if( !PyArg_ParseTuple( args, "iO", &nurb_num, &coord_args ) )
781                 return ( EXPP_ReturnPyObjError
782                          ( PyExc_TypeError,
783                            "expected int, coords as arguments" ) );
784
785         /* 
786            chase down the list of Nurbs looking for our curve.
787          */
788         for( i = 0; i < nurb_num; i++ ) {
789                 nurb = nurb->next;
790                 if( !nurb )     /* we ran off end of list */
791                         return EXPP_ReturnPyObjError( PyExc_ValueError,
792                                         "curve index out of range" );
793         }
794         return CurNurb_appendPointToNurb( nurb, coord_args );
795 }
796
797
798 /****
799   appendNurb( new_point )
800   create a new nurb in the Curve and add the point param to it.
801   returns a refernce to the newly created nurb.
802 *****/
803
804 static PyObject *Curve_appendNurb( BPy_Curve * self, PyObject * value )
805 {
806         Nurb *new_nurb;
807         /* malloc new nurb */
808         new_nurb = ( Nurb * ) MEM_callocN( sizeof( Nurb ), "appendNurb" );
809         if( !new_nurb )
810                 return EXPP_ReturnPyObjError
811                         ( PyExc_MemoryError, "unable to malloc Nurb" );
812         
813         if( CurNurb_appendPointToNurb( new_nurb, value ) ) {
814                 new_nurb->resolu = self->curve->resolu;
815                 new_nurb->resolv = self->curve->resolv;
816                 new_nurb->hide = 0;
817                 new_nurb->flag = 1;
818
819
820                 if( new_nurb->bezt ) {  /* do setup for bezt */
821                         new_nurb->type = CU_BEZIER;
822                         new_nurb->bezt->h1 = HD_ALIGN;
823                         new_nurb->bezt->h2 = HD_ALIGN;
824                         new_nurb->bezt->f1 = 1;
825                         new_nurb->bezt->f2 = 1;
826                         new_nurb->bezt->f3 = 1;
827                         new_nurb->bezt->hide = 0;
828                         /* calchandlesNurb( new_nurb ); */
829                 } else {        /* set up bp */
830                         new_nurb->pntsv = 1;
831                         new_nurb->type = CU_NURBS;
832                         new_nurb->orderu = 4;
833                         new_nurb->flagu = 0;
834                         new_nurb->flagv = 0;
835                         new_nurb->bp->f1 = 0;
836                         new_nurb->bp->hide = 0;
837                         new_nurb->knotsu = 0;
838                         /*makenots( new_nurb, 1, new_nurb->flagu >> 1); */
839                 }
840                 BLI_addtail( &self->curve->nurb, new_nurb);
841
842         } else {
843                 freeNurb( new_nurb );
844                 return NULL;    /* with PyErr already set */
845         }
846
847         return CurNurb_CreatePyObject( new_nurb );
848 }
849
850
851 /* 
852  *   Curve_update( )
853  *   method to update display list for a Curve.
854  *   used. after messing with control points
855  */
856
857 PyObject *Curve_update( BPy_Curve * self )
858 {
859         Nurb *nu = self->curve->nurb.first;
860
861         /* recalculate handles for each curve: calchandlesNurb() will make
862          * sure curves are bezier first */
863         while( nu ) {
864                 calchandlesNurb ( nu );
865                 nu = nu->next;
866         }
867
868         Object_updateDag( (void*) self->curve );
869
870         Py_RETURN_NONE;
871 }
872
873 /*
874  * Curve_getMaterials
875  *
876  */
877
878 static PyObject *Curve_getMaterials( BPy_Curve * self )
879 {
880         return EXPP_PyList_fromMaterialList( self->curve->mat,
881                         self->curve->totcol, 1 );
882 }
883
884 static int Curve_setMaterials( BPy_Curve *self, PyObject * value )
885 {
886         Material **matlist;
887         int len;
888
889         if( !PySequence_Check( value ) ||
890                         !EXPP_check_sequence_consistency( value, &Material_Type ) )
891                 return EXPP_ReturnIntError( PyExc_TypeError,
892                                 "sequence should only contain materials or None)" );
893
894         len = PySequence_Size( value );
895         if( len > 16 )
896                 return EXPP_ReturnIntError( PyExc_TypeError,
897                         "list can't have more than 16 materials" );
898
899         /* free old material list (if it exists) and adjust user counts */
900         if( self->curve->mat ) {
901                 Curve *cur = self->curve;
902                 int i;
903                 for( i = cur->totcol; i-- > 0; )
904                         if( cur->mat[i] )
905                         cur->mat[i]->id.us--;
906                 MEM_freeN( cur->mat );
907         }
908
909         /* build the new material list, increment user count, store it */
910
911         matlist = EXPP_newMaterialList_fromPyList( value );
912         EXPP_incr_mats_us( matlist, len );
913         self->curve->mat = matlist;
914         self->curve->totcol = (short)len;
915
916 /**@ This is another ugly fix due to the weird material handling of blender.
917     * it makes sure that object material lists get updated (by their length)
918     * according to their data material lists, otherwise blender crashes.
919     * It just stupidly runs through all objects...BAD BAD BAD.
920     */
921
922         test_object_materials( ( ID * ) self->curve );
923
924         return 0;
925 }
926
927 /*****************************************************************************/
928 /* Function:    Curve_getBevOb                                               */
929 /* Description: Get the bevel object assign to the curve.                    */
930 /*****************************************************************************/
931 static PyObject *Curve_getBevOb( BPy_Curve * self)
932 {
933         if( self->curve->bevobj ) {
934                 return Object_CreatePyObject( self->curve->bevobj );
935         }
936
937         return EXPP_incr_ret( Py_None );
938 }
939
940 /*****************************************************************************/
941 /* Function:    Curve_newsetBevOb                                            */
942 /* Description: Assign a bevel object to the curve.                          */
943 /*****************************************************************************/
944 static int Curve_newsetBevOb( BPy_Curve * self, PyObject * args )
945 {
946         
947         if (BPy_Object_Check( args ) && ((BPy_Object *)args)->object->data == self->curve )
948                 return EXPP_ReturnIntError( PyExc_ValueError,
949                                 "Can't bevel an object to itself" );
950         
951         return GenericLib_assignData(args, (void **) &self->curve->bevobj, 0, 0, ID_OB, OB_CURVE);
952 }
953
954 /*****************************************************************************/
955 /* Function:    Curve_getTaperOb                                             */
956 /* Description: Get the taper object assign to the curve.                    */
957 /*****************************************************************************/
958
959 static PyObject *Curve_getTaperOb( BPy_Curve * self)
960 {
961         if( self->curve->taperobj )
962                 return Object_CreatePyObject( self->curve->taperobj );
963
964         Py_RETURN_NONE;
965 }
966
967 /*****************************************************************************/
968 /* Function:    Curve_newsetTaperOb                                          */
969 /* Description: Assign a taper object to the curve.                          */
970 /*****************************************************************************/
971
972 static int Curve_newsetTaperOb( BPy_Curve * self, PyObject * args )
973 {
974         if (BPy_Object_Check( args ) && ((BPy_Object *)args)->object->data == self->curve )
975                 return EXPP_ReturnIntError( PyExc_ValueError,
976                                 "Can't taper an object to itself" );
977         
978         return GenericLib_assignData(args, (void **) &self->curve->taperobj, 0, 0, ID_OB, OB_CURVE);
979 }
980
981 /*****************************************************************************/
982 /* Function:    Curve_copy                                                   */
983 /* Description: Return a copy of this curve data.                            */
984 /*****************************************************************************/
985
986 PyObject *Curve_copy( BPy_Curve * self )
987 {
988         BPy_Curve *pycurve;     /* for Curve Data object wrapper in Python */
989         Curve *blcurve = 0;     /* for actual Curve Data we create in Blender */
990
991         /* copies the data */
992         blcurve = copy_curve( self->curve );    /* first create the Curve Data in Blender */
993
994         if( blcurve == NULL )   /* bail out if add_curve() failed */
995                 return ( EXPP_ReturnPyObjError
996                          ( PyExc_RuntimeError,
997                            "couldn't create Curve Data in Blender" ) );
998
999         /* return user count to zero because add_curve() inc'd it */
1000         blcurve->id.us = 0;
1001         
1002         /* create python wrapper obj */
1003         pycurve = ( BPy_Curve * ) PyObject_NEW( BPy_Curve, &Curve_Type );
1004
1005         if( pycurve == NULL )
1006                 return ( EXPP_ReturnPyObjError
1007                          ( PyExc_MemoryError,
1008                            "couldn't create Curve Data object" ) );
1009
1010         pycurve->curve = blcurve;       /* link Python curve wrapper to Blender Curve */
1011         return ( PyObject * ) pycurve;
1012 }
1013
1014
1015 /*
1016  * Curve_getIter
1017  *
1018  * create an iterator for our Curve.
1019  * this iterator returns the Nurbs for this Curve.
1020  * the iter_pointer always points to the next available item or null
1021  */
1022
1023 static PyObject *Curve_getIter( BPy_Curve * self )
1024 {
1025         self->iter_pointer = self->curve->nurb.first;
1026
1027         Py_INCREF( self );
1028         return ( PyObject * ) self;
1029
1030 }
1031
1032
1033 /*
1034  * Curve_iterNext
1035  *  get the next item.
1036  *  iter_pointer always points to the next available element
1037  *   or NULL if at the end of the list.
1038  */
1039
1040 static PyObject *Curve_iterNext( BPy_Curve * self )
1041 {
1042         Nurb *pnurb;
1043
1044         if( self->iter_pointer ) {
1045                 pnurb = self->iter_pointer;
1046                 self->iter_pointer = pnurb->next;       /* advance iterator */
1047                 if( (pnurb->type & 7) == CU_BEZIER || pnurb->pntsv <= 1 )
1048                         return CurNurb_CreatePyObject( pnurb ); /* make a bpy_curnurb */
1049                 else
1050                         return SurfNurb_CreatePyObject( pnurb ); /* make a bpy_surfnurb */
1051         }
1052
1053         /* if iter_pointer was null, we are at end */
1054         return EXPP_ReturnPyObjError( PyExc_StopIteration,
1055                         "iterator at end" );
1056 }
1057
1058 /* tp_sequence methods */
1059
1060 /*
1061  * Curve_length
1062  * returns the number of curves in a Curve
1063  * this is a tp_as_sequence method, not a regular instance method.
1064  */
1065
1066 static int Curve_length( PyInstanceObject * inst )
1067 {
1068         if( BPy_Curve_Check( ( PyObject * ) inst ) )
1069                 return ( ( int ) PyInt_AsLong
1070                          ( Curve_getNumCurves( ( BPy_Curve * ) inst ) ) );
1071
1072         return EXPP_ReturnIntError( PyExc_RuntimeError,
1073                                     "arg is not a BPy_Curve" );
1074
1075 }
1076
1077 /*
1078  * Curve_getNurb
1079  * returns the Nth nurb in a Curve.
1080  * this is one of the tp_as_sequence methods, hence the int N argument.
1081  * it is called via the [] operator, not as a usual instance method.
1082  */
1083
1084 PyObject *Curve_getNurb( BPy_Curve * self, int n )
1085 {
1086         Nurb *pNurb;
1087         int i;
1088
1089         /* bail if index < 0 */
1090         if( n < 0 )
1091                 return ( EXPP_ReturnPyObjError( PyExc_IndexError,
1092                                                 "index less than 0" ) );
1093         /* bail if no Nurbs in Curve */
1094         if( self->curve->nurb.first == 0 )
1095                 return ( EXPP_ReturnPyObjError( PyExc_IndexError,
1096                                                 "no Nurbs in this Curve" ) );
1097         /* set pointer to nth Nurb */
1098         for( pNurb = self->curve->nurb.first, i = 0;
1099              pNurb != 0 && i < n; pNurb = pNurb->next, ++i )
1100                 /**/;
1101
1102         if( !pNurb )            /* we came to the end of the list */
1103                 return ( EXPP_ReturnPyObjError( PyExc_IndexError,
1104                                                 "index out of range" ) );
1105
1106         /* until there is a Surface BPyType, distinquish between a curve and a
1107          * surface based on whether it's a Bezier and the v size */
1108         if( (pNurb->type & 7) == CU_BEZIER || pNurb->pntsv <= 1 )
1109                 return CurNurb_CreatePyObject( pNurb ); /* make a bpy_curnurb */
1110         else
1111                 return SurfNurb_CreatePyObject( pNurb );        /* make a bpy_surfnurb */
1112
1113 }
1114
1115 /*
1116  * Curve_setNurb
1117  * In this case only remove the item, we could allow adding later.
1118  */
1119 static int Curve_setNurb( BPy_Curve * self, int n, PyObject * value )
1120 {
1121         Nurb *pNurb;
1122         int i;
1123
1124         /* bail if index < 0 */
1125         if( n < 0 )
1126                 return ( EXPP_ReturnIntError( PyExc_IndexError,
1127                                  "index less than 0" ) );
1128         /* bail if no Nurbs in Curve */
1129         if( self->curve->nurb.first == 0 )
1130                 return ( EXPP_ReturnIntError( PyExc_IndexError,
1131                                  "no Nurbs in this Curve" ) );
1132         /* set pointer to nth Nurb */
1133         for( pNurb = self->curve->nurb.first, i = 0;
1134                         pNurb != 0 && i < n; pNurb = pNurb->next, ++i )
1135                 /**/;
1136
1137         if( !pNurb )            /* we came to the end of the list */
1138                 return ( EXPP_ReturnIntError( PyExc_IndexError,
1139                                  "index out of range" ) );
1140         
1141         if (value) {
1142                 return ( EXPP_ReturnIntError( PyExc_RuntimeError,
1143                                  "assigning curves is not yet supported" ) );
1144         } else {
1145                 BLI_remlink(&self->curve->nurb, pNurb);
1146                 freeNurb(pNurb);
1147         }
1148         return 0;
1149 }
1150
1151 /*****************************************************************************/
1152 /* Function:    Curve_compare                                                    */
1153 /* Description: This compares 2 curve python types, == or != only.                       */
1154 /*****************************************************************************/
1155 static int Curve_compare( BPy_Curve * a, BPy_Curve * b )
1156 {
1157         return ( a->curve == b->curve ) ? 0 : -1;
1158 }
1159
1160 /*****************************************************************************/
1161 /* Function:    Curve_repr                                                   */
1162 /* Description: This is a callback function for the BPy_Curve type. It       */
1163 /*              builds a meaninful string to represent curve objects.        */
1164 /*****************************************************************************/
1165 static PyObject *Curve_repr( BPy_Curve * self )
1166 {                               /* used by 'repr' */
1167
1168         return PyString_FromFormat( "[Curve \"%s\"]",
1169                                     self->curve->id.name + 2 );
1170 }
1171
1172 /* attributes for curves */
1173
1174 static PyGetSetDef Curve_getseters[] = {
1175         GENERIC_LIB_GETSETATTR,
1176         {"pathlen",
1177          (getter)Curve_getPathLen, (setter)Curve_newsetPathLen,
1178          "The path length,  used to set the number of frames for an animation (not the physical length)",
1179         NULL},
1180         {"totcol",
1181          (getter)Curve_getTotcol, (setter)NULL,
1182          "The maximum number of linked materials",
1183         NULL},
1184         {"flag",
1185          (getter)Curve_getMode, (setter)Curve_newsetMode,
1186          "The flag bitmask",
1187         NULL},
1188         {"bevresol",
1189          (getter)Curve_getBevresol, (setter)Curve_newsetBevresol,
1190          "The bevel resolution",
1191         NULL},
1192         {"resolu",
1193          (getter)Curve_getResolu, (setter)Curve_newsetResolu,
1194          "The resolution in U direction",
1195         NULL},
1196         {"resolv",
1197          (getter)Curve_getResolv, (setter)Curve_newsetResolv,
1198          "The resolution in V direction",
1199         NULL},
1200         {"width",
1201          (getter)Curve_getWidth, (setter)Curve_newsetWidth,
1202          "The curve width",
1203         NULL},
1204         {"ext1",
1205          (getter)Curve_getExt1, (setter)Curve_newsetExt1,
1206          "The extent1 value (for bevels)",
1207         NULL},
1208         {"ext2",
1209          (getter)Curve_getExt2, (setter)Curve_newsetExt2,
1210          "The extent2 value (for bevels)",
1211         NULL},
1212         {"loc",
1213          (getter)Curve_getLoc, (setter)Curve_newsetLoc,
1214          "The data location (from the center)",
1215         NULL},
1216         {"rot",
1217          (getter)Curve_getRot, (setter)Curve_newsetRot,
1218          "The data rotation (from the center)",
1219         NULL},
1220         {"size",
1221          (getter)Curve_getSize, (setter)Curve_newsetSize,
1222          "The data size (from the center)",
1223         NULL},
1224         {"bevob",
1225          (getter)Curve_getBevOb, (setter)Curve_newsetBevOb,
1226          "The bevel object",
1227         NULL},
1228         {"taperob",
1229          (getter)Curve_getTaperOb, (setter)Curve_newsetTaperOb,
1230          "The taper object",
1231         NULL},
1232         {"key",
1233          (getter)Curve_getKey, (setter)NULL,
1234          "The shape key for the curve (if any)",
1235         NULL},
1236         {"materials",
1237          (getter)Curve_getMaterials, (setter)Curve_setMaterials,
1238          "The materials associated with the curve",
1239         NULL},
1240         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
1241
1242 };
1243
1244 /*****************************************************************************/
1245 /* Function:              M_Curve_New                                       */
1246 /* Python equivalent:     Blender.Curve.New                                 */
1247 /*****************************************************************************/
1248 static PyObject *M_Curve_New( PyObject * self, PyObject * args )
1249 {
1250         char *name = "Curve";
1251         BPy_Curve *pycurve;     /* for Curve Data object wrapper in Python */
1252         Curve *blcurve = 0;     /* for actual Curve Data we create in Blender */
1253
1254         if( !PyArg_ParseTuple( args, "|s", &name ) )
1255                 return ( EXPP_ReturnPyObjError
1256                          ( PyExc_TypeError,
1257                            "expected string argument or no argument" ) );
1258
1259         blcurve = add_curve( name, OB_CURVE );  /* first create the Curve Data in Blender */
1260
1261         if( blcurve == NULL )   /* bail out if add_curve() failed */
1262                 return ( EXPP_ReturnPyObjError
1263                          ( PyExc_RuntimeError,
1264                            "couldn't create Curve Data in Blender" ) );
1265
1266         /* return user count to zero because add_curve() inc'd it */
1267         blcurve->id.us = 0;
1268         /* create python wrapper obj */
1269         pycurve = ( BPy_Curve * ) PyObject_NEW( BPy_Curve, &Curve_Type );
1270
1271         if( pycurve == NULL )
1272                 return ( EXPP_ReturnPyObjError
1273                          ( PyExc_MemoryError,
1274                            "couldn't create Curve Data object" ) );
1275
1276         pycurve->curve = blcurve;       /* link Python curve wrapper to Blender Curve */
1277         
1278         return ( PyObject * ) pycurve;
1279 }
1280
1281 /*****************************************************************************/
1282 /* Function:              M_Curve_Get                                       */
1283 /* Python equivalent:     Blender.Curve.Get                                 */
1284 /*****************************************************************************/
1285 static PyObject *M_Curve_Get( PyObject * self, PyObject * args )
1286 {
1287
1288         char *name = NULL;
1289         Curve *curv_iter;
1290         BPy_Curve *wanted_curv;
1291
1292         if( !PyArg_ParseTuple( args, "|s", &name ) )    /* expects nothing or a string */
1293                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1294                                                 "expected string argument" ) );
1295         if( name ) {            /*a name has been given */
1296                 /* Use the name to search for the curve requested */
1297                 wanted_curv = NULL;
1298                 curv_iter = G.main->curve.first;
1299
1300                 while( ( curv_iter ) && ( wanted_curv == NULL ) ) {
1301
1302                         if( strcmp( name, curv_iter->id.name + 2 ) == 0 ) {
1303                                 wanted_curv = ( BPy_Curve * )
1304                                         PyObject_NEW( BPy_Curve, &Curve_Type );
1305                                 if( wanted_curv )
1306                                         wanted_curv->curve = curv_iter;
1307                         }
1308
1309                         curv_iter = curv_iter->id.next;
1310                 }
1311
1312                 if( wanted_curv == NULL ) {     /* Requested curve doesn't exist */
1313                         char error_msg[64];
1314                         PyOS_snprintf( error_msg, sizeof( error_msg ),
1315                                        "Curve \"%s\" not found", name );
1316                         return ( EXPP_ReturnPyObjError
1317                                  ( PyExc_NameError, error_msg ) );
1318                 }
1319
1320
1321                 return ( PyObject * ) wanted_curv;
1322         } /* end  of if(name) */
1323         else {
1324                 /* no name has been given; return a list of all curves by name.  */
1325                 PyObject *curvlist;
1326
1327                 curv_iter = G.main->curve.first;
1328                 curvlist = PyList_New( 0 );
1329
1330                 if( curvlist == NULL )
1331                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
1332                                                         "couldn't create PyList" ) );
1333
1334                 while( curv_iter ) {
1335                         BPy_Curve *found_cur =
1336                                 ( BPy_Curve * ) PyObject_NEW( BPy_Curve,
1337                                                               &Curve_Type );
1338                         found_cur->curve = curv_iter;
1339                         PyList_Append( curvlist, ( PyObject * ) found_cur );
1340                         Py_DECREF(found_cur);
1341                         curv_iter = curv_iter->id.next;
1342                 }
1343
1344                 return ( curvlist );
1345         }                       /* end of else */
1346 }
1347
1348 /*****************************************************************************/
1349 /*  Python method definitions for Blender.Curve module:             */
1350 /*****************************************************************************/
1351 struct PyMethodDef M_Curve_methods[] = {
1352         {"New", ( PyCFunction ) M_Curve_New, METH_VARARGS, M_Curve_New_doc},
1353         {"Get", M_Curve_Get, METH_VARARGS, M_Curve_Get_doc},
1354         {"get", M_Curve_Get, METH_VARARGS, M_Curve_Get_doc},
1355         {NULL, NULL, 0, NULL}
1356 };
1357
1358
1359 /*****************************************************************************/
1360 /*  Python BPy_Curve instance methods table:                                 */
1361 /*****************************************************************************/
1362 static PyMethodDef BPy_Curve_methods[] = {
1363         {"getName", ( PyCFunction ) Curve_getName,
1364          METH_NOARGS, "() - Return Curve Data name"},
1365         {"setName", ( PyCFunction ) Curve_setName,
1366          METH_VARARGS, "() - Sets Curve Data name"},
1367         {"getPathLen", ( PyCFunction ) Curve_getPathLen,
1368          METH_NOARGS, "() - Return Curve path length"},
1369         {"setPathLen", ( PyCFunction ) Curve_setPathLen,
1370          METH_VARARGS, "(int) - Sets Curve path length"},
1371         {"getTotcol", ( PyCFunction ) Curve_getTotcol,
1372          METH_NOARGS, "() - Return the number of materials of the curve"},
1373         {"setTotcol", ( PyCFunction ) Curve_setTotcol,
1374          METH_VARARGS, "(int) - Sets the number of materials of the curve"},
1375         {"getFlag", ( PyCFunction ) Curve_getMode,
1376          METH_NOARGS, "() - Return flag (see the doc for semantic)"},
1377         {"setFlag", ( PyCFunction ) Curve_setMode,
1378          METH_VARARGS, "(int) - Sets flag (see the doc for semantic)"},
1379         {"getBevresol", ( PyCFunction ) Curve_getBevresol,
1380          METH_NOARGS, "() - Return bevel resolution"},
1381         {"setBevresol", ( PyCFunction ) Curve_setBevresol,
1382          METH_VARARGS, "(int) - Sets bevel resolution"},
1383         {"getResolu", ( PyCFunction ) Curve_getResolu,
1384          METH_NOARGS, "() - Return U resolution"},
1385         {"setResolu", ( PyCFunction ) Curve_setResolu,
1386          METH_VARARGS, "(int) - Sets U resolution"},
1387         {"getResolv", ( PyCFunction ) Curve_getResolv,
1388          METH_NOARGS, "() - Return V resolution"},
1389         {"setResolv", ( PyCFunction ) Curve_setResolv,
1390          METH_VARARGS, "(int) - Sets V resolution"},
1391         {"getWidth", ( PyCFunction ) Curve_getWidth,
1392          METH_NOARGS, "() - Return curve width"},
1393         {"setWidth", ( PyCFunction ) Curve_setWidth,
1394          METH_VARARGS, "(int) - Sets curve width"},
1395         {"getExt1", ( PyCFunction ) Curve_getExt1,
1396          METH_NOARGS, "() - Returns extent 1 of the bevel"},
1397         {"setExt1", ( PyCFunction ) Curve_setExt1,
1398          METH_VARARGS, "(int) - Sets  extent 1 of the bevel"},
1399         {"getExt2", ( PyCFunction ) Curve_getExt2,
1400          METH_NOARGS, "() - Return extent 2 of the bevel "},
1401         {"setExt2", ( PyCFunction ) Curve_setExt2,
1402          METH_VARARGS, "(int) - Sets extent 2 of the bevel "},
1403         {"getControlPoint", ( PyCFunction ) Curve_getControlPoint,
1404          METH_VARARGS, "(int numcurve,int numpoint) -\
1405 Gets a control point.Depending upon the curve type, returne a list of 4 or 9 floats"},
1406         {"setControlPoint", ( PyCFunction ) Curve_setControlPoint,
1407          METH_VARARGS, "(int numcurve,int numpoint,float x,float y,float z,\
1408 float w)(nurbs) or  (int numcurve,int numpoint,float x1,...,x9(bezier)\
1409 Sets a control point "},
1410         {"getLoc", ( PyCFunction ) Curve_getLoc,
1411          METH_NOARGS, "() - Gets Location of the curve (a 3-tuple) "},
1412         {"setLoc", ( PyCFunction ) Curve_setLoc,
1413          METH_VARARGS, "(3-tuple) - Sets Location "},
1414         {"getRot", ( PyCFunction ) Curve_getRot,
1415          METH_NOARGS, "() - Gets curve rotation"},
1416         {"setRot", ( PyCFunction ) Curve_setRot,
1417          METH_VARARGS, "(3-tuple) - Sets curve rotation"},
1418         {"getSize", ( PyCFunction ) Curve_getSize,
1419          METH_NOARGS, "() - Gets curve size"},
1420         {"setSize", ( PyCFunction ) Curve_setSize,
1421          METH_VARARGS, "(3-tuple) - Sets curve size"},
1422         {"getNumCurves", ( PyCFunction ) Curve_getNumCurves,
1423          METH_NOARGS, "() - Gets number of curves in Curve"},
1424         {"getKey", ( PyCFunction ) Curve_getKey,
1425          METH_NOARGS, "() - Gets curve key"},
1426         {"isNurb", ( PyCFunction ) Curve_isNurb,
1427          METH_VARARGS,
1428          "(nothing or integer) - returns 1 if curve is type Nurb, O otherwise."},
1429         {"isCyclic", ( PyCFunction ) Curve_isCyclic,
1430          METH_VARARGS, "( nothing or integer ) - returns true if curve is cyclic (closed), false otherwise."},
1431         {"getNumPoints", ( PyCFunction ) Curve_getNumPoints,
1432          METH_VARARGS,
1433          "(nothing or integer) - returns the number of points of the specified curve"},
1434         {"appendPoint", ( PyCFunction ) Curve_appendPoint, METH_VARARGS,
1435          "( int numcurve, list of coordinates) - adds a new point to end of curve"},
1436         {"appendNurb", ( PyCFunction ) Curve_appendNurb, METH_O,
1437          "( new_nurb ) - adds a new nurb to the Curve"},
1438         {"update", ( PyCFunction ) Curve_update, METH_NOARGS,
1439          "( ) - updates display lists after changes to Curve"},
1440         {"getMaterials", ( PyCFunction ) Curve_getMaterials, METH_NOARGS,
1441          "() - returns list of materials assigned to this Curve"},
1442         {"getBevOb", ( PyCFunction ) Curve_getBevOb, METH_NOARGS,
1443          "() - returns Bevel Object assigned to this Curve"},
1444         {"setBevOb", ( PyCFunction ) Curve_setBevOb, METH_VARARGS,
1445          "() - assign a Bevel Object to this Curve"},
1446         {"getTaperOb", ( PyCFunction ) Curve_getTaperOb, METH_NOARGS,
1447          "() - returns Taper Object assigned to this Curve"},
1448         {"setTaperOb", ( PyCFunction ) Curve_setTaperOb, METH_VARARGS,
1449          "() - assign a Taper Object to this Curve"},
1450         {"__copy__", ( PyCFunction ) Curve_copy, METH_NOARGS,
1451          "() - make a copy of this curve data"},
1452         {"copy", ( PyCFunction ) Curve_copy, METH_NOARGS,
1453          "() - make a copy of this curve data"},
1454         {NULL, NULL, 0, NULL}
1455 };
1456
1457
1458 /*****************************************************************************/
1459 /*  Python Curve_Type callback function prototypes:                         */
1460 /*****************************************************************************/
1461 static int Curve_compare( BPy_Curve * a, BPy_Curve * b );
1462 static PyObject *Curve_repr( BPy_Curve * msh );
1463
1464 static PySequenceMethods Curve_as_sequence = {
1465         ( inquiry ) Curve_length,       /* sq_length   */
1466         ( binaryfunc ) 0,       /* sq_concat */
1467         ( intargfunc ) 0,       /* sq_repeat */
1468         ( intargfunc ) Curve_getNurb,   /* sq_item */
1469         ( intintargfunc ) 0,    /* sq_slice */
1470         ( intobjargproc ) Curve_setNurb,        /* sq_ass_item - only so you can do del curve[i] */
1471         0,                      /* sq_ass_slice */
1472         ( objobjproc ) 0,       /* sq_contains */
1473         0,
1474         0
1475 };
1476
1477 /*****************************************************************************/
1478 /* Python Curve_Type structure definition:                                   */
1479 /*****************************************************************************/
1480 PyTypeObject Curve_Type = {
1481         PyObject_HEAD_INIT( NULL )          /* required macro */ 
1482         0,                                  /* ob_size */
1483         "Curve",                            /* tp_name */
1484         sizeof( BPy_Curve ),                /* tp_basicsize */
1485         0,                                  /* tp_itemsize */
1486         /* methods */
1487         NULL,                                                           /* tp_dealloc */
1488         0,                                  /* tp_print */
1489         ( getattrfunc ) NULL,               /* tp_getattr */
1490         ( setattrfunc ) NULL,               /* tp_setattr */
1491         ( cmpfunc ) Curve_compare,          /* tp_compare */
1492         ( reprfunc ) Curve_repr,            /* tp_repr */
1493         /* Method suites for standard classes */
1494
1495         NULL,                               /* PyNumberMethods *tp_as_number; */
1496         &Curve_as_sequence,                 /* PySequenceMethods *tp_as_sequence; */
1497         NULL,                               /* PyMappingMethods *tp_as_mapping; */
1498
1499         /* More standard operations (here for binary compatibility) */
1500
1501         ( hashfunc ) GenericLib_hash,           /* hashfunc tp_hash; */
1502         NULL,                               /* ternaryfunc tp_call; */
1503         NULL,                               /* reprfunc tp_str; */
1504         NULL,                               /* getattrofunc tp_getattro; */
1505         NULL,                               /* setattrofunc tp_setattro; */
1506
1507         /* Functions to access object as input/output buffer */
1508         NULL,                               /* PyBufferProcs *tp_as_buffer; */
1509
1510   /*** Flags to define presence of optional/expanded features ***/
1511         Py_TPFLAGS_DEFAULT,                 /* long tp_flags; */
1512
1513         NULL,                               /*  char *tp_doc;  */
1514   /*** Assigned meaning in release 2.0 ***/
1515         /* call function for all accessible objects */
1516         NULL,                               /* traverseproc tp_traverse; */
1517
1518         /* delete references to contained objects */
1519         NULL,                               /* inquiry tp_clear; */
1520
1521   /***  Assigned meaning in release 2.1 ***/
1522   /*** rich comparisons ***/
1523         NULL,                               /* richcmpfunc tp_richcompare; */
1524
1525   /***  weak reference enabler ***/
1526         0,                                  /* long tp_weaklistoffset; */
1527
1528   /*** Added in release 2.2 ***/
1529         /*   Iterators */
1530         ( getiterfunc ) Curve_getIter,      /* getiterfunc tp_iter; */
1531         ( iternextfunc ) Curve_iterNext,        /* iternextfunc tp_iternext; */
1532
1533   /*** Attribute descriptor and subclassing stuff ***/
1534         BPy_Curve_methods,                  /* struct PyMethodDef *tp_methods; */
1535         NULL,                               /* struct PyMemberDef *tp_members; */
1536         Curve_getseters,                    /* struct PyGetSetDef *tp_getset; */
1537         NULL,                               /* struct _typeobject *tp_base; */
1538         NULL,                               /* PyObject *tp_dict; */
1539         NULL,                               /* descrgetfunc tp_descr_get; */
1540         NULL,                               /* descrsetfunc tp_descr_set; */
1541         0,                                  /* long tp_dictoffset; */
1542         NULL,                               /* initproc tp_init; */
1543         NULL,                               /* allocfunc tp_alloc; */
1544         NULL,                               /* newfunc tp_new; */
1545         /*  Low-level free-memory routine */
1546         NULL,                               /* freefunc tp_free;  */
1547         /* For PyObject_IS_GC */
1548         NULL,                               /* inquiry tp_is_gc;  */
1549         NULL,                               /* PyObject *tp_bases; */
1550         /* method resolution order */
1551         NULL,                               /* PyObject *tp_mro;  */
1552         NULL,                               /* PyObject *tp_cache; */
1553         NULL,                               /* PyObject *tp_subclasses; */
1554         NULL,                               /* PyObject *tp_weaklist; */
1555         NULL
1556 };
1557
1558
1559 /*****************************************************************************/
1560 /* Function:              Curve_Init                                         */
1561 /*****************************************************************************/
1562 PyObject *Curve_Init( void )
1563 {
1564         PyObject *submodule;
1565
1566         if( PyType_Ready( &Curve_Type) < 0) /* set exception.  -1 is failure */
1567                 return NULL;
1568
1569         submodule =
1570                 Py_InitModule3( "Blender.Curve", M_Curve_methods,
1571                                 M_Curve_doc );
1572         return ( submodule );
1573 }
1574
1575
1576 /*
1577  * Curve_CreatePyObject
1578  * constructor to build a py object from blender data 
1579  */
1580
1581 PyObject *Curve_CreatePyObject( struct Curve * curve )
1582 {
1583         BPy_Curve *blen_object;
1584
1585         blen_object = ( BPy_Curve * ) PyObject_NEW( BPy_Curve, &Curve_Type );
1586
1587         if( blen_object == NULL ) {
1588                 return ( NULL );
1589         }
1590         blen_object->curve = curve;
1591         return ( ( PyObject * ) blen_object );
1592
1593 }
1594
1595 struct Curve *Curve_FromPyObject( PyObject * py_obj )
1596 {
1597         BPy_Curve *blen_obj;
1598
1599         blen_obj = ( BPy_Curve * ) py_obj;
1600         return ( blen_obj->curve );
1601
1602 }
1603
1604 /* #####DEPRECATED###### */
1605
1606 PyObject *Curve_setName( BPy_Curve * self, PyObject * args )
1607 {
1608         return EXPP_setterWrapper( (void *)self, args, (setter)Curve_newsetName );
1609 }
1610
1611 static PyObject *Curve_setPathLen( BPy_Curve * self, PyObject * args )
1612 {
1613         return EXPP_setterWrapper( (void *)self, args,
1614                         (setter)Curve_newsetPathLen );
1615 }
1616
1617 static PyObject *Curve_setTotcol( BPy_Curve * self, PyObject * args )
1618 {
1619         if( !PyArg_ParseTuple( args, "i", &( self->curve->totcol ) ) )
1620                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1621                                 "expected int argument" );
1622         Py_RETURN_NONE;
1623 }
1624
1625 PyObject *Curve_setMode( BPy_Curve * self, PyObject * args )
1626 {
1627         return EXPP_setterWrapper( (void *)self, args,
1628                         (setter)Curve_newsetMode );
1629 }
1630
1631 PyObject *Curve_setBevresol( BPy_Curve * self, PyObject * args )
1632 {
1633         return EXPP_setterWrapper( (void *)self, args,
1634                         (setter)Curve_newsetBevresol);
1635 }
1636
1637 PyObject *Curve_setResolu( BPy_Curve * self, PyObject * args )
1638 {
1639         return EXPP_setterWrapper( (void *)self, args,
1640                         (setter)Curve_newsetResolu );
1641 }
1642
1643 PyObject *Curve_setResolv( BPy_Curve * self, PyObject * args )
1644 {
1645         return EXPP_setterWrapper( (void *)self, args,
1646                         (setter)Curve_newsetResolv );
1647 }
1648
1649 PyObject *Curve_setWidth( BPy_Curve * self, PyObject * args )
1650 {
1651         return EXPP_setterWrapper( (void *)self, args,
1652                         (setter)Curve_newsetWidth );
1653 }
1654
1655 PyObject *Curve_setExt1( BPy_Curve * self, PyObject * args )
1656 {
1657         return EXPP_setterWrapper( (void *)self, args,
1658                         (setter)Curve_newsetExt1 );
1659 }
1660
1661 PyObject *Curve_setExt2( BPy_Curve * self, PyObject * args )
1662 {
1663         return EXPP_setterWrapper( (void *)self, args,
1664                         (setter)Curve_newsetExt2 );
1665 }
1666
1667 static PyObject *Curve_setLoc( BPy_Curve * self, PyObject * args )
1668 {
1669         return EXPP_setterWrapper( (void *)self, args,
1670                         (setter)Curve_newsetLoc );
1671 }
1672
1673 static PyObject *Curve_setRot( BPy_Curve * self, PyObject * args )
1674 {
1675         return EXPP_setterWrapper( (void *)self, args,
1676                         (setter)Curve_newsetRot );
1677 }
1678
1679 static PyObject *Curve_setSize( BPy_Curve * self, PyObject * args )
1680 {
1681         return EXPP_setterWrapper( (void *)self, args,
1682                         (setter)Curve_newsetSize );
1683 }
1684
1685 PyObject *Curve_setBevOb( BPy_Curve * self, PyObject * args )
1686 {
1687         return EXPP_setterWrapper( (void *)self, args,
1688                         (setter)Curve_newsetBevOb );
1689 }
1690
1691 PyObject *Curve_setTaperOb( BPy_Curve * self, PyObject * args )
1692 {
1693         return EXPP_setterWrapper( (void *)self, args,
1694                         (setter)Curve_newsetTaperOb );
1695 }
1696