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