svn merge -r 12607:12653 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_length( PyInstanceObject * inst );
128
129
130 struct chartrans *text_to_curve( Object * ob, int mode );
131 /*****************************************************************************/
132 /* Python BPy_Curve methods:                                                 */
133 /* gives access to                                                           */
134 /* name, pathlen totcol flag bevresol                                        */
135 /* resolu resolv width ext1 ext2                                             */
136 /* controlpoint loc rot size                                                 */
137 /* numpts                                                                    */
138 /*****************************************************************************/
139
140
141 PyObject *Curve_getName( BPy_Curve * self )
142 {
143         return PyString_FromString( self->curve->id.name + 2 );
144 }
145
146 static int Curve_newsetName( BPy_Curve * self, PyObject * args )
147 {
148         char *name;
149
150         name = PyString_AsString( args );
151         if( !name )
152                 return EXPP_ReturnIntError( PyExc_TypeError,
153                                               "expected string argument" );
154
155         rename_id( &self->curve->id, name );    /* proper way in Blender */
156         Curve_update( self );
157
158         return 0;
159 }
160
161 static PyObject *Curve_getPathLen( BPy_Curve * self )
162 {
163         return PyInt_FromLong( ( long ) self->curve->pathlen );
164 }
165
166
167 static int Curve_newsetPathLen( BPy_Curve * self, PyObject * args )
168 {
169         PyObject *num;
170
171         if( !PyNumber_Check( args ) )
172                 return EXPP_ReturnIntError( PyExc_TypeError,
173                                 "expected int argument" );
174
175         num = PyNumber_Int( args );
176         self->curve->pathlen = (short)PyInt_AS_LONG( num );
177         Py_DECREF( num );
178
179         return 0;
180 }
181
182 static PyObject *Curve_getTotcol( BPy_Curve * self )
183 {
184         return PyInt_FromLong( ( long ) self->curve->totcol );
185 }
186
187
188 PyObject *Curve_getMode( BPy_Curve * self )
189 {
190         return PyInt_FromLong( ( long ) self->curve->flag );
191 }
192
193
194 static int Curve_newsetMode( BPy_Curve * self, PyObject * args )
195 {
196         PyObject *num;
197
198         if( !PyNumber_Check( args ) )
199                 return EXPP_ReturnIntError( PyExc_TypeError,
200                                 "expected int argument" );
201
202         num = PyNumber_Int( args );
203         self->curve->flag = (short)PyInt_AS_LONG( num );
204         Py_DECREF( num );
205
206         return 0;
207 }
208
209 PyObject *Curve_getBevresol( BPy_Curve * self )
210 {
211         return PyInt_FromLong( ( long ) self->curve->bevresol );
212 }
213
214 static int Curve_newsetBevresol( BPy_Curve * self, PyObject * args )
215 {
216         short value;
217         PyObject *num;
218
219         if( !PyNumber_Check( args ) )
220                 return EXPP_ReturnIntError( PyExc_TypeError,
221                                 "expected int argument" );
222
223         num = PyNumber_Int( args );
224         value = (short)PyInt_AS_LONG( num );
225         Py_DECREF( num );
226
227         if( value > 10 || value < 0 )
228                 return EXPP_ReturnIntError( PyExc_ValueError,
229                                 "acceptable values are between 0 and 10" );
230
231         self->curve->bevresol = value;
232         return 0;
233 }
234
235
236 PyObject *Curve_getResolu( BPy_Curve * self )
237 {
238         return PyInt_FromLong( ( long ) self->curve->resolu );
239 }
240
241
242 static int Curve_newsetResolu( BPy_Curve * self, PyObject * args )
243 {
244         short value;
245         Nurb *nu;
246         PyObject *num;
247
248         if( !PyNumber_Check( args ) )
249                 return EXPP_ReturnIntError( PyExc_TypeError,
250                                 "expected int argument" );
251
252         num = PyNumber_Int( args );
253         value = (short)PyInt_AS_LONG( num );
254         Py_DECREF( num );
255
256         if( value > 128 || value < 1 )
257                 return EXPP_ReturnIntError( PyExc_ValueError,
258                                 "acceptable values are between 1 and 128" );
259
260         self->curve->resolu = value;
261         /* propagate the change through all the curves */
262         for( nu = self->curve->nurb.first; nu; nu = nu->next )
263                 nu->resolu = value;
264
265         return 0;
266 }
267
268 PyObject *Curve_getResolv( BPy_Curve * self )
269 {
270         return PyInt_FromLong( ( long ) self->curve->resolv );
271 }
272
273 static int Curve_newsetResolv( BPy_Curve * self, PyObject * args )
274 {
275         short value;
276         PyObject *num;
277
278         if( !PyNumber_Check( args ) )
279                 return EXPP_ReturnIntError( PyExc_TypeError,
280                                 "expected int argument" );
281
282         num = PyNumber_Int( args );
283         value = (short)PyInt_AS_LONG( num );
284         Py_DECREF( num );
285
286         if(value > 128 || value < 1)
287                 return EXPP_ReturnIntError( PyExc_ValueError,
288                         "acceptable values are between 1 and 128" );
289         self->curve->resolv = value;
290
291         return 0;
292 }
293
294 PyObject *Curve_getWidth( BPy_Curve * self )
295 {
296         return PyFloat_FromDouble( ( double ) self->curve->width );
297 }
298
299
300 static int Curve_newsetWidth( BPy_Curve * self, PyObject * args )
301 {
302         float value;
303         PyObject *num;
304
305         if( !PyNumber_Check( args ) )
306                 return EXPP_ReturnIntError( PyExc_TypeError,
307                                 "expected float argument" );
308
309         num = PyNumber_Float( args );
310         value = (float)PyFloat_AS_DOUBLE( num );
311         Py_DECREF( num );
312
313         if(value > 2.0f || value < 0.0f)
314                 return EXPP_ReturnIntError( PyExc_ValueError,
315                                 "acceptable values are between 2.0 and 0.0" );
316         self->curve->width = value;
317
318         return 0;
319 }
320
321
322 PyObject *Curve_getExt1( BPy_Curve * self )
323 {
324         return PyFloat_FromDouble( ( double ) self->curve->ext1 );
325 }
326
327
328 static int Curve_newsetExt1( BPy_Curve * self, PyObject * args )
329 {
330         float value;
331         PyObject *num;
332
333         if( !PyNumber_Check( args ) )
334                 return EXPP_ReturnIntError( PyExc_TypeError,
335                                 "expected float argument" );
336
337         num = PyNumber_Float( args );
338         value = (float)PyFloat_AS_DOUBLE( num );
339         Py_DECREF( num );
340
341         if(value > 100.0f || value < 0.0f)
342                 return EXPP_ReturnIntError( PyExc_ValueError,
343                                 "acceptable values are between 0.0 and 100.0" );
344         self->curve->ext1 = value;
345
346         return 0;
347 }
348
349 PyObject *Curve_getExt2( BPy_Curve * self )
350 {
351         return PyFloat_FromDouble( ( double ) self->curve->ext2 );
352 }
353
354
355 static int Curve_newsetExt2( BPy_Curve * self, PyObject * args )
356 {
357         float value;
358         PyObject *num;
359
360         if( !PyNumber_Check( args ) )
361                 return EXPP_ReturnIntError( PyExc_TypeError,
362                                 "expected float argument" );
363
364         num = PyNumber_Float( args );
365         value = (float)PyFloat_AS_DOUBLE( num );
366         Py_DECREF( num );
367
368         if(value > 2.0f || value < 0.0f)
369                 return EXPP_ReturnIntError( PyExc_ValueError,
370                                 "acceptable values are between 0.0 and 2.0" );
371         self->curve->ext2 = value;
372
373         return 0;
374 }
375
376 /*
377  * Curve_setControlPoint
378  * this function sets an EXISTING control point.
379  * it does NOT add a new one.
380  */
381
382 static PyObject *Curve_setControlPoint( BPy_Curve * self, PyObject * args )
383 {
384         PyObject *listargs = 0;
385         Nurb *ptrnurb = self->curve->nurb.first;
386         int numcourbe = 0, numpoint = 0, i, j;
387
388         if( !ptrnurb )
389                 Py_RETURN_NONE;
390
391         if( ptrnurb->bp )
392                 if( !PyArg_ParseTuple
393                     ( args, "iiO", &numcourbe, &numpoint, &listargs ) )
394                         return ( EXPP_ReturnPyObjError
395                                  ( PyExc_TypeError,
396                                    "expected int, int, list arguments" ) );
397         if( ptrnurb->bezt )
398                 if( !PyArg_ParseTuple
399                     ( args, "iiO", &numcourbe, &numpoint, &listargs ) )
400                         return ( EXPP_ReturnPyObjError
401                                  ( PyExc_TypeError,
402                                    "expected int, int, list arguments" ) );
403
404         for( i = 0; i < numcourbe; i++ )
405                 ptrnurb = ptrnurb->next;
406
407         if( ptrnurb->bp )
408                 for( i = 0; i < 4; i++ )
409                         ptrnurb->bp[numpoint].vec[i] =
410                                 (float)PyFloat_AsDouble( PyList_GetItem ( listargs, i ) );
411
412         if( ptrnurb->bezt )
413                 for( i = 0; i < 3; i++ )
414                         for( j = 0; j < 3; j++ )
415                                 ptrnurb->bezt[numpoint].vec[i][j] =
416                                         (float)PyFloat_AsDouble( PyList_GetItem
417                                                           ( listargs,
418                                                             i * 3 + j ) );
419
420         Py_RETURN_NONE;
421 }
422
423
424 static PyObject *Curve_getControlPoint( BPy_Curve * self, PyObject * args )
425 {
426         PyObject *liste;
427         PyObject *item;
428
429         Nurb *ptrnurb;
430         int i, j;
431         /* input args: requested curve and point number on curve */
432         int numcourbe, numpoint;
433
434         if( !PyArg_ParseTuple( args, "ii", &numcourbe, &numpoint ) )
435                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
436                                         "expected int int arguments" ) );
437         if( ( numcourbe < 0 ) || ( numpoint < 0 ) )
438                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
439                                                 "arguments must be non-negative" ) );
440
441         /* if no nurbs in this curve obj */
442         if( !self->curve->nurb.first )
443                 return PyList_New( 0 );
444
445         /* walk the list of nurbs to find requested numcourbe */
446         ptrnurb = self->curve->nurb.first;
447         for( i = 0; i < numcourbe; i++ ) {
448                 ptrnurb = ptrnurb->next;
449                 if( !ptrnurb )  /* if zero, we ran just ran out of curves */
450                         return ( EXPP_ReturnPyObjError( PyExc_ValueError,
451                                                         "curve index out of range" ) );
452         }
453
454         /* check numpoint param against pntsu */
455         if( numpoint >= ptrnurb->pntsu )
456                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
457                                                 "point index out of range" ) );
458         
459         liste = PyList_New( 0 );
460         if( ptrnurb->bp ) {     /* if we are a nurb curve, you get 4 values */
461                 for( i = 0; i < 4; i++ ) {
462                         item = PyFloat_FromDouble( ptrnurb->bp[numpoint].vec[i] );
463                         PyList_Append( liste, item );
464                         Py_DECREF(item);
465                 }
466         } else if( ptrnurb->bezt ) {    /* if we are a bezier, you get 9 values */
467                 for( i = 0; i < 3; i++ )
468                         for( j = 0; j < 3; j++ ) {
469                                 item = PyFloat_FromDouble( ptrnurb->bezt[numpoint].vec[i][j] );
470                                 PyList_Append( liste, item );
471                                 Py_DECREF(item);
472                         }
473         }
474
475         return liste;
476 }
477
478 static PyObject *Curve_getLoc( BPy_Curve * self )
479 {
480         return Py_BuildValue( "[f,f,f]", self->curve->loc[0],
481                                 self->curve->loc[1], self->curve->loc[2] );
482 }
483
484 static int Curve_newsetLoc( BPy_Curve * self, PyObject * args )
485 {
486         float loc[3];
487         int i;
488
489         if( ( !PyList_Check( args ) && !PyTuple_Check( args ) ) ||
490                         PySequence_Size( args ) != 3 ) {
491 TypeError:
492                 return EXPP_ReturnIntError( PyExc_TypeError,
493                                 "expected a sequence of three floats" );
494         }
495
496         for( i = 0; i < 3; i++ ) {
497                 PyObject *item = PySequence_GetItem( args, i );
498                 PyObject *num = PyNumber_Float( item );
499                 Py_DECREF( item );
500                 if( !num )
501                         goto TypeError;
502                 loc[i] = PyFloat_AS_DOUBLE( num );
503                 Py_DECREF( num );
504         }
505         memcpy( self->curve->loc, loc, sizeof( loc ) );
506
507         return 0;
508 }
509
510 static PyObject *Curve_getRot( BPy_Curve * self )
511 {
512         return Py_BuildValue( "[f,f,f]", self->curve->rot[0],
513                                 self->curve->rot[1], self->curve->rot[2] );
514 }
515
516 static int Curve_newsetRot( BPy_Curve * self, PyObject * args )
517 {
518         float rot[3];
519         int i;
520
521         if( ( !PyList_Check( args ) && !PyTuple_Check( args ) ) ||
522                         PySequence_Size( args ) != 3 ) {
523 TypeError:
524                 return EXPP_ReturnIntError( PyExc_TypeError,
525                                 "expected a sequence of three floats" );
526         }
527
528         for( i = 0; i < 3; i++ ) {
529                 PyObject *item = PySequence_GetItem( args, i );
530                 PyObject *num = PyNumber_Float( item );
531                 Py_DECREF( item );
532                 if( !num )
533                         goto TypeError;
534                 rot[i] = PyFloat_AS_DOUBLE( num );
535                 Py_DECREF( num );
536         }
537         memcpy( self->curve->rot, rot, sizeof( rot ) );
538
539         return 0;
540 }
541
542 static PyObject *Curve_getSize( BPy_Curve * self )
543 {
544         return Py_BuildValue( "[f,f,f]", self->curve->size[0],
545                                 self->curve->size[1], self->curve->size[2] );
546 }
547
548 static int Curve_newsetSize( BPy_Curve * self, PyObject * args )
549 {
550         float size[3];
551         int i;
552
553         if( ( !PyList_Check( args ) && !PyTuple_Check( args ) ) ||
554                         PySequence_Size( args ) != 3 ) {
555 TypeError:
556                 return EXPP_ReturnIntError( PyExc_TypeError,
557                                 "expected a sequence of three floats" );
558         }
559
560         for( i = 0; i < 3; i++ ) {
561                 PyObject *item = PySequence_GetItem( args, i );
562                 PyObject *num = PyNumber_Float( item );
563                 Py_DECREF( item );
564                 if( !num )
565                         goto TypeError;
566                 size[i] = PyFloat_AS_DOUBLE( num );
567                 Py_DECREF( num );
568         }
569         memcpy( self->curve->size, size, sizeof( size ) );
570
571         return 0;
572 }
573
574 /*
575  * Count the number of splines in a Curve Object
576  * int getNumCurves()
577  */
578
579 static PyObject *Curve_getNumCurves( BPy_Curve * self )
580 {
581         Nurb *ptrnurb;
582         PyObject *ret_val;
583         int num_curves = 0;     /* start with no splines */
584
585         /* get curve */
586         ptrnurb = self->curve->nurb.first;
587         if( ptrnurb ) {         /* we have some nurbs in this curve */
588                 for(;;) {
589                         ++num_curves;
590                         ptrnurb = ptrnurb->next;
591                         if( !ptrnurb )  /* no more curves */
592                                 break;
593                 }
594         }
595
596         ret_val = PyInt_FromLong( ( long ) num_curves );
597
598         if( ret_val )
599                 return ret_val;
600
601         /* oops! */
602         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
603                                         "couldn't get number of curves" );
604 }
605
606 /*
607  * get the key object linked to this curve
608  */
609
610 static PyObject *Curve_getKey( BPy_Curve * self )
611 {
612         PyObject *keyObj;
613
614         if (self->curve->key)
615                 keyObj = Key_CreatePyObject(self->curve->key);
616         else keyObj = EXPP_incr_ret(Py_None);
617
618         return keyObj;
619 }
620
621 /*
622  * count the number of points in a given spline
623  * int getNumPoints( curve_num=0 )
624  *
625  */
626
627 static PyObject *Curve_getNumPoints( BPy_Curve * self, PyObject * args )
628 {
629         Nurb *ptrnurb;
630         PyObject *ret_val;
631         int curve_num = 0;      /* default spline number */
632         int i;
633
634         /* parse input arg */
635         if( !PyArg_ParseTuple( args, "|i", &curve_num ) )
636                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
637                                                 "expected int argument" ) );
638
639         /* check arg - must be non-negative */
640         if( curve_num < 0 )
641                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
642                                                 "argument must be non-negative" ) );
643
644
645         /* walk the list of curves looking for our curve */
646         ptrnurb = self->curve->nurb.first;
647         if( !ptrnurb ) {        /* no splines in this Curve */
648                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
649                                                 "no splines in this Curve" ) );
650         }
651
652         for( i = 0; i < curve_num; i++ ) {
653                 ptrnurb = ptrnurb->next;
654                 if( !ptrnurb )  /* if zero, we ran just ran out of curves */
655                         return ( EXPP_ReturnPyObjError( PyExc_ValueError,
656                                                         "curve index out of range" ) );
657         }
658
659         /* pntsu is the number of points in curve */
660         ret_val = PyInt_FromLong( ( long ) ptrnurb->pntsu );
661
662         if( ret_val )
663                 return ret_val;
664
665         /* oops! */
666         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
667                         "couldn't get number of points for curve" );
668 }
669
670 /*
671  * Test whether a given spline of a Curve is a nurb
672  *  as opposed to a bezier
673  * int isNurb( curve_num=0 )
674  */
675
676 static PyObject *Curve_isNurb( BPy_Curve * self, PyObject * args )
677 {
678         int curve_num = 0;      /* default value */
679         int is_nurb;
680         Nurb *ptrnurb;
681         PyObject *ret_val;
682         int i;
683
684         /* parse and check input args */
685         if( !PyArg_ParseTuple( args, "|i", &curve_num ) ) {
686                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
687                                                 "expected int argument" ) );
688         }
689         if( curve_num < 0 ) {
690                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
691                                                 "curve number must be non-negative" ) );
692         }
693
694         ptrnurb = self->curve->nurb.first;
695
696         if( !ptrnurb )          /* no splines in this curve */
697                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
698                                                 "no splines in this Curve" ) );
699
700         for( i = 0; i < curve_num; i++ ) {
701                 ptrnurb = ptrnurb->next;
702                 if( !ptrnurb )  /* if zero, we ran just ran out of curves */
703                         return ( EXPP_ReturnPyObjError( PyExc_ValueError,
704                                                         "curve index out of range" ) );
705         }
706
707         /* right now, there are only two curve types, nurb and bezier. */
708         is_nurb = ptrnurb->bp ? 1 : 0;
709
710         ret_val = PyInt_FromLong( ( long ) is_nurb );
711         if( ret_val )
712                 return ret_val;
713
714         /* oops */
715         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
716                                         "couldn't get curve type" ) );
717 }
718
719 /* trying to make a check for closedness (cyclic), following on isNurb (above) 
720    copy-pasting done by antont@kyperjokki.fi */
721
722 static PyObject *Curve_isCyclic( BPy_Curve * self, PyObject * args )
723 {
724         int curve_num = 0;      /* default value */
725         /* unused:*/
726         /* int is_cyclic;
727          * PyObject *ret_val;*/
728         Nurb *ptrnurb;
729         int i;
730
731         /* parse and check input args */
732         if( !PyArg_ParseTuple( args, "|i", &curve_num ) ) {
733                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
734                                                 "expected int argument" ) );
735         }
736         if( curve_num < 0 ) {
737                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
738                                                 "curve number must be non-negative" ) );
739         }
740
741         ptrnurb = self->curve->nurb.first;
742
743         if( !ptrnurb )          /* no splines in this curve */
744                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
745                                                 "no splines in this Curve" ) );
746
747         for( i = 0; i < curve_num; i++ ) {
748                 ptrnurb = ptrnurb->next;
749                 if( !ptrnurb )  /* if zero, we ran just ran out of curves */
750                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
751                                                         "curve index out of range" ) );
752         }
753
754         if(  ptrnurb->flagu & CU_CYCLIC ){
755                 return EXPP_incr_ret_True();
756         } else {
757                 return EXPP_incr_ret_False();
758         }
759 }
760
761
762 /*
763  * Curve_appendPoint( numcurve, new_point )
764  * append a new point to indicated spline
765  */
766
767 static PyObject *Curve_appendPoint( BPy_Curve * self, PyObject * args )
768 {
769         int i;
770         int nurb_num;           /* index of curve we append to */
771         PyObject *coord_args;   /* coords for new point */
772         Nurb *nurb = self->curve->nurb.first;   /* first nurb in Curve */
773
774 /* fixme - need to malloc new Nurb */
775         if( !nurb )
776                 return ( EXPP_ReturnPyObjError
777                          ( PyExc_AttributeError, "no nurbs in this Curve" ) );
778
779         if( !PyArg_ParseTuple( args, "iO", &nurb_num, &coord_args ) )
780                 return ( EXPP_ReturnPyObjError
781                          ( PyExc_TypeError,
782                            "expected int, coords as arguments" ) );
783
784         /* 
785            chase down the list of Nurbs looking for our curve.
786          */
787         for( i = 0; i < nurb_num; i++ ) {
788                 nurb = nurb->next;
789                 if( !nurb )     /* we ran off end of list */
790                         return EXPP_ReturnPyObjError( PyExc_ValueError,
791                                         "curve index out of range" );
792         }
793         return CurNurb_appendPointToNurb( nurb, coord_args );
794 }
795
796
797 /****
798   appendNurb( new_point )
799   create a new nurb in the Curve and add the point param to it.
800   returns a refernce to the newly created nurb.
801 *****/
802
803 static PyObject *Curve_appendNurb( BPy_Curve * self, PyObject * value )
804 {
805         Nurb *new_nurb;
806         /* malloc new nurb */
807         new_nurb = ( Nurb * ) MEM_callocN( sizeof( Nurb ), "appendNurb" );
808         if( !new_nurb )
809                 return EXPP_ReturnPyObjError
810                         ( PyExc_MemoryError, "unable to malloc Nurb" );
811         
812         if( CurNurb_appendPointToNurb( new_nurb, value ) ) {
813                 new_nurb->resolu = self->curve->resolu;
814                 new_nurb->resolv = self->curve->resolv;
815                 new_nurb->hide = 0;
816                 new_nurb->flag = 1;
817
818
819                 if( new_nurb->bezt ) {  /* do setup for bezt */
820                         new_nurb->type = CU_BEZIER;
821                         new_nurb->bezt->h1 = HD_ALIGN;
822                         new_nurb->bezt->h2 = HD_ALIGN;
823                         new_nurb->bezt->f1 = 1;
824                         new_nurb->bezt->f2 = 1;
825                         new_nurb->bezt->f3 = 1;
826                         new_nurb->bezt->hide = 0;
827                         /* calchandlesNurb( new_nurb ); */
828                 } else {        /* set up bp */
829                         new_nurb->pntsv = 1;
830                         new_nurb->type = CU_NURBS;
831                         new_nurb->orderu = 4;
832                         new_nurb->flagu = 0;
833                         new_nurb->flagv = 0;
834                         new_nurb->bp->f1 = 0;
835                         new_nurb->bp->hide = 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 /* Function:    Curve_compare                                                    */
1116 /* Description: This compares 2 curve python types, == or != only.                       */
1117 /*****************************************************************************/
1118 static int Curve_compare( BPy_Curve * a, BPy_Curve * b )
1119 {
1120         return ( a->curve == b->curve ) ? 0 : -1;
1121 }
1122
1123 /*****************************************************************************/
1124 /* Function:    Curve_repr                                                   */
1125 /* Description: This is a callback function for the BPy_Curve type. It       */
1126 /*              builds a meaninful string to represent curve objects.        */
1127 /*****************************************************************************/
1128 static PyObject *Curve_repr( BPy_Curve * self )
1129 {                               /* used by 'repr' */
1130
1131         return PyString_FromFormat( "[Curve \"%s\"]",
1132                                     self->curve->id.name + 2 );
1133 }
1134
1135 /* attributes for curves */
1136
1137 static PyGetSetDef Curve_getseters[] = {
1138         GENERIC_LIB_GETSETATTR,
1139         {"pathlen",
1140          (getter)Curve_getPathLen, (setter)Curve_newsetPathLen,
1141          "The path length,  used to set the number of frames for an animation (not the physical length)",
1142         NULL},
1143         {"totcol",
1144          (getter)Curve_getTotcol, (setter)NULL,
1145          "The maximum number of linked materials",
1146         NULL},
1147         {"flag",
1148          (getter)Curve_getMode, (setter)Curve_newsetMode,
1149          "The flag bitmask",
1150         NULL},
1151         {"bevresol",
1152          (getter)Curve_getBevresol, (setter)Curve_newsetBevresol,
1153          "The bevel resolution",
1154         NULL},
1155         {"resolu",
1156          (getter)Curve_getResolu, (setter)Curve_newsetResolu,
1157          "The resolution in U direction",
1158         NULL},
1159         {"resolv",
1160          (getter)Curve_getResolv, (setter)Curve_newsetResolv,
1161          "The resolution in V direction",
1162         NULL},
1163         {"width",
1164          (getter)Curve_getWidth, (setter)Curve_newsetWidth,
1165          "The curve width",
1166         NULL},
1167         {"ext1",
1168          (getter)Curve_getExt1, (setter)Curve_newsetExt1,
1169          "The extent1 value (for bevels)",
1170         NULL},
1171         {"ext2",
1172          (getter)Curve_getExt2, (setter)Curve_newsetExt2,
1173          "The extent2 value (for bevels)",
1174         NULL},
1175         {"loc",
1176          (getter)Curve_getLoc, (setter)Curve_newsetLoc,
1177          "The data location (from the center)",
1178         NULL},
1179         {"rot",
1180          (getter)Curve_getRot, (setter)Curve_newsetRot,
1181          "The data rotation (from the center)",
1182         NULL},
1183         {"size",
1184          (getter)Curve_getSize, (setter)Curve_newsetSize,
1185          "The data size (from the center)",
1186         NULL},
1187         {"bevob",
1188          (getter)Curve_getBevOb, (setter)Curve_newsetBevOb,
1189          "The bevel object",
1190         NULL},
1191         {"taperob",
1192          (getter)Curve_getTaperOb, (setter)Curve_newsetTaperOb,
1193          "The taper object",
1194         NULL},
1195         {"key",
1196          (getter)Curve_getKey, (setter)NULL,
1197          "The shape key for the curve (if any)",
1198         NULL},
1199         {"materials",
1200          (getter)Curve_getMaterials, (setter)Curve_setMaterials,
1201          "The materials associated with the curve",
1202         NULL},
1203         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
1204
1205 };
1206
1207 /*****************************************************************************/
1208 /* Function:              M_Curve_New                                       */
1209 /* Python equivalent:     Blender.Curve.New                                 */
1210 /*****************************************************************************/
1211 static PyObject *M_Curve_New( PyObject * self, PyObject * args )
1212 {
1213         char *name = "Curve";
1214         BPy_Curve *pycurve;     /* for Curve Data object wrapper in Python */
1215         Curve *blcurve = 0;     /* for actual Curve Data we create in Blender */
1216
1217         if( !PyArg_ParseTuple( args, "|s", &name ) )
1218                 return ( EXPP_ReturnPyObjError
1219                          ( PyExc_TypeError,
1220                            "expected string argument or no argument" ) );
1221
1222         blcurve = add_curve( name, OB_CURVE );  /* first create the Curve Data in Blender */
1223
1224         if( blcurve == NULL )   /* bail out if add_curve() failed */
1225                 return ( EXPP_ReturnPyObjError
1226                          ( PyExc_RuntimeError,
1227                            "couldn't create Curve Data in Blender" ) );
1228
1229         /* return user count to zero because add_curve() inc'd it */
1230         blcurve->id.us = 0;
1231         /* create python wrapper obj */
1232         pycurve = ( BPy_Curve * ) PyObject_NEW( BPy_Curve, &Curve_Type );
1233
1234         if( pycurve == NULL )
1235                 return ( EXPP_ReturnPyObjError
1236                          ( PyExc_MemoryError,
1237                            "couldn't create Curve Data object" ) );
1238
1239         pycurve->curve = blcurve;       /* link Python curve wrapper to Blender Curve */
1240         
1241         return ( PyObject * ) pycurve;
1242 }
1243
1244 /*****************************************************************************/
1245 /* Function:              M_Curve_Get                                       */
1246 /* Python equivalent:     Blender.Curve.Get                                 */
1247 /*****************************************************************************/
1248 static PyObject *M_Curve_Get( PyObject * self, PyObject * args )
1249 {
1250
1251         char *name = NULL;
1252         Curve *curv_iter;
1253         BPy_Curve *wanted_curv;
1254
1255         if( !PyArg_ParseTuple( args, "|s", &name ) )    /* expects nothing or a string */
1256                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1257                                                 "expected string argument" ) );
1258         if( name ) {            /*a name has been given */
1259                 /* Use the name to search for the curve requested */
1260                 wanted_curv = NULL;
1261                 curv_iter = G.main->curve.first;
1262
1263                 while( ( curv_iter ) && ( wanted_curv == NULL ) ) {
1264
1265                         if( strcmp( name, curv_iter->id.name + 2 ) == 0 ) {
1266                                 wanted_curv = ( BPy_Curve * )
1267                                         PyObject_NEW( BPy_Curve, &Curve_Type );
1268                                 if( wanted_curv )
1269                                         wanted_curv->curve = curv_iter;
1270                         }
1271
1272                         curv_iter = curv_iter->id.next;
1273                 }
1274
1275                 if( wanted_curv == NULL ) {     /* Requested curve doesn't exist */
1276                         char error_msg[64];
1277                         PyOS_snprintf( error_msg, sizeof( error_msg ),
1278                                        "Curve \"%s\" not found", name );
1279                         return ( EXPP_ReturnPyObjError
1280                                  ( PyExc_NameError, error_msg ) );
1281                 }
1282
1283
1284                 return ( PyObject * ) wanted_curv;
1285         } /* end  of if(name) */
1286         else {
1287                 /* no name has been given; return a list of all curves by name.  */
1288                 PyObject *curvlist;
1289
1290                 curv_iter = G.main->curve.first;
1291                 curvlist = PyList_New( 0 );
1292
1293                 if( curvlist == NULL )
1294                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
1295                                                         "couldn't create PyList" ) );
1296
1297                 while( curv_iter ) {
1298                         BPy_Curve *found_cur =
1299                                 ( BPy_Curve * ) PyObject_NEW( BPy_Curve,
1300                                                               &Curve_Type );
1301                         found_cur->curve = curv_iter;
1302                         PyList_Append( curvlist, ( PyObject * ) found_cur );
1303                         Py_DECREF(found_cur);
1304                         curv_iter = curv_iter->id.next;
1305                 }
1306
1307                 return ( curvlist );
1308         }                       /* end of else */
1309 }
1310
1311 /*****************************************************************************/
1312 /*  Python method definitions for Blender.Curve module:             */
1313 /*****************************************************************************/
1314 struct PyMethodDef M_Curve_methods[] = {
1315         {"New", ( PyCFunction ) M_Curve_New, METH_VARARGS, M_Curve_New_doc},
1316         {"Get", M_Curve_Get, METH_VARARGS, M_Curve_Get_doc},
1317         {"get", M_Curve_Get, METH_VARARGS, M_Curve_Get_doc},
1318         {NULL, NULL, 0, NULL}
1319 };
1320
1321
1322 /*****************************************************************************/
1323 /*  Python BPy_Curve instance methods table:                                 */
1324 /*****************************************************************************/
1325 static PyMethodDef BPy_Curve_methods[] = {
1326         {"getName", ( PyCFunction ) Curve_getName,
1327          METH_NOARGS, "() - Return Curve Data name"},
1328         {"setName", ( PyCFunction ) Curve_setName,
1329          METH_VARARGS, "() - Sets Curve Data name"},
1330         {"getPathLen", ( PyCFunction ) Curve_getPathLen,
1331          METH_NOARGS, "() - Return Curve path length"},
1332         {"setPathLen", ( PyCFunction ) Curve_setPathLen,
1333          METH_VARARGS, "(int) - Sets Curve path length"},
1334         {"getTotcol", ( PyCFunction ) Curve_getTotcol,
1335          METH_NOARGS, "() - Return the number of materials of the curve"},
1336         {"setTotcol", ( PyCFunction ) Curve_setTotcol,
1337          METH_VARARGS, "(int) - Sets the number of materials of the curve"},
1338         {"getFlag", ( PyCFunction ) Curve_getMode,
1339          METH_NOARGS, "() - Return flag (see the doc for semantic)"},
1340         {"setFlag", ( PyCFunction ) Curve_setMode,
1341          METH_VARARGS, "(int) - Sets flag (see the doc for semantic)"},
1342         {"getBevresol", ( PyCFunction ) Curve_getBevresol,
1343          METH_NOARGS, "() - Return bevel resolution"},
1344         {"setBevresol", ( PyCFunction ) Curve_setBevresol,
1345          METH_VARARGS, "(int) - Sets bevel resolution"},
1346         {"getResolu", ( PyCFunction ) Curve_getResolu,
1347          METH_NOARGS, "() - Return U resolution"},
1348         {"setResolu", ( PyCFunction ) Curve_setResolu,
1349          METH_VARARGS, "(int) - Sets U resolution"},
1350         {"getResolv", ( PyCFunction ) Curve_getResolv,
1351          METH_NOARGS, "() - Return V resolution"},
1352         {"setResolv", ( PyCFunction ) Curve_setResolv,
1353          METH_VARARGS, "(int) - Sets V resolution"},
1354         {"getWidth", ( PyCFunction ) Curve_getWidth,
1355          METH_NOARGS, "() - Return curve width"},
1356         {"setWidth", ( PyCFunction ) Curve_setWidth,
1357          METH_VARARGS, "(int) - Sets curve width"},
1358         {"getExt1", ( PyCFunction ) Curve_getExt1,
1359          METH_NOARGS, "() - Returns extent 1 of the bevel"},
1360         {"setExt1", ( PyCFunction ) Curve_setExt1,
1361          METH_VARARGS, "(int) - Sets  extent 1 of the bevel"},
1362         {"getExt2", ( PyCFunction ) Curve_getExt2,
1363          METH_NOARGS, "() - Return extent 2 of the bevel "},
1364         {"setExt2", ( PyCFunction ) Curve_setExt2,
1365          METH_VARARGS, "(int) - Sets extent 2 of the bevel "},
1366         {"getControlPoint", ( PyCFunction ) Curve_getControlPoint,
1367          METH_VARARGS, "(int numcurve,int numpoint) -\
1368 Gets a control point.Depending upon the curve type, returne a list of 4 or 9 floats"},
1369         {"setControlPoint", ( PyCFunction ) Curve_setControlPoint,
1370          METH_VARARGS, "(int numcurve,int numpoint,float x,float y,float z,\
1371 float w)(nurbs) or  (int numcurve,int numpoint,float x1,...,x9(bezier)\
1372 Sets a control point "},
1373         {"getLoc", ( PyCFunction ) Curve_getLoc,
1374          METH_NOARGS, "() - Gets Location of the curve (a 3-tuple) "},
1375         {"setLoc", ( PyCFunction ) Curve_setLoc,
1376          METH_VARARGS, "(3-tuple) - Sets Location "},
1377         {"getRot", ( PyCFunction ) Curve_getRot,
1378          METH_NOARGS, "() - Gets curve rotation"},
1379         {"setRot", ( PyCFunction ) Curve_setRot,
1380          METH_VARARGS, "(3-tuple) - Sets curve rotation"},
1381         {"getSize", ( PyCFunction ) Curve_getSize,
1382          METH_NOARGS, "() - Gets curve size"},
1383         {"setSize", ( PyCFunction ) Curve_setSize,
1384          METH_VARARGS, "(3-tuple) - Sets curve size"},
1385         {"getNumCurves", ( PyCFunction ) Curve_getNumCurves,
1386          METH_NOARGS, "() - Gets number of curves in Curve"},
1387         {"getKey", ( PyCFunction ) Curve_getKey,
1388          METH_NOARGS, "() - Gets curve key"},
1389         {"isNurb", ( PyCFunction ) Curve_isNurb,
1390          METH_VARARGS,
1391          "(nothing or integer) - returns 1 if curve is type Nurb, O otherwise."},
1392         {"isCyclic", ( PyCFunction ) Curve_isCyclic,
1393          METH_VARARGS, "( nothing or integer ) - returns true if curve is cyclic (closed), false otherwise."},
1394         {"getNumPoints", ( PyCFunction ) Curve_getNumPoints,
1395          METH_VARARGS,
1396          "(nothing or integer) - returns the number of points of the specified curve"},
1397         {"appendPoint", ( PyCFunction ) Curve_appendPoint, METH_VARARGS,
1398          "( int numcurve, list of coordinates) - adds a new point to end of curve"},
1399         {"appendNurb", ( PyCFunction ) Curve_appendNurb, METH_O,
1400          "( new_nurb ) - adds a new nurb to the Curve"},
1401         {"update", ( PyCFunction ) Curve_update, METH_NOARGS,
1402          "( ) - updates display lists after changes to Curve"},
1403         {"getMaterials", ( PyCFunction ) Curve_getMaterials, METH_NOARGS,
1404          "() - returns list of materials assigned to this Curve"},
1405         {"getBevOb", ( PyCFunction ) Curve_getBevOb, METH_NOARGS,
1406          "() - returns Bevel Object assigned to this Curve"},
1407         {"setBevOb", ( PyCFunction ) Curve_setBevOb, METH_VARARGS,
1408          "() - assign a Bevel Object to this Curve"},
1409         {"getTaperOb", ( PyCFunction ) Curve_getTaperOb, METH_NOARGS,
1410          "() - returns Taper Object assigned to this Curve"},
1411         {"setTaperOb", ( PyCFunction ) Curve_setTaperOb, METH_VARARGS,
1412          "() - assign a Taper Object to this Curve"},
1413         {"__copy__", ( PyCFunction ) Curve_copy, METH_NOARGS,
1414          "() - make a copy of this curve data"},
1415         {"copy", ( PyCFunction ) Curve_copy, METH_NOARGS,
1416          "() - make a copy of this curve data"},
1417         {NULL, NULL, 0, NULL}
1418 };
1419
1420
1421 /*****************************************************************************/
1422 /*  Python Curve_Type callback function prototypes:                         */
1423 /*****************************************************************************/
1424 static int Curve_compare( BPy_Curve * a, BPy_Curve * b );
1425 static PyObject *Curve_repr( BPy_Curve * msh );
1426
1427 static PySequenceMethods Curve_as_sequence = {
1428         ( inquiry ) Curve_length,       /* sq_length   */
1429         ( binaryfunc ) 0,       /* sq_concat */
1430         ( intargfunc ) 0,       /* sq_repeat */
1431         ( intargfunc ) Curve_getNurb,   /* sq_item */
1432         ( intintargfunc ) 0,    /* sq_slice */
1433         0,                      /* sq_ass_item */
1434         0,                      /* sq_ass_slice */
1435         ( objobjproc ) 0,       /* sq_contains */
1436         0,
1437         0
1438 };
1439
1440 /*****************************************************************************/
1441 /* Python Curve_Type structure definition:                                   */
1442 /*****************************************************************************/
1443 PyTypeObject Curve_Type = {
1444         PyObject_HEAD_INIT( NULL )          /* required macro */ 
1445         0,                                  /* ob_size */
1446         "Curve",                            /* tp_name */
1447         sizeof( BPy_Curve ),                /* tp_basicsize */
1448         0,                                  /* tp_itemsize */
1449         /* methods */
1450         NULL,                                                           /* tp_dealloc */
1451         0,                                  /* tp_print */
1452         ( getattrfunc ) NULL,               /* tp_getattr */
1453         ( setattrfunc ) NULL,               /* tp_setattr */
1454         ( cmpfunc ) Curve_compare,          /* tp_compare */
1455         ( reprfunc ) Curve_repr,            /* tp_repr */
1456         /* Method suites for standard classes */
1457
1458         NULL,                               /* PyNumberMethods *tp_as_number; */
1459         &Curve_as_sequence,                 /* PySequenceMethods *tp_as_sequence; */
1460         NULL,                               /* PyMappingMethods *tp_as_mapping; */
1461
1462         /* More standard operations (here for binary compatibility) */
1463
1464         ( hashfunc ) GenericLib_hash,           /* hashfunc tp_hash; */
1465         NULL,                               /* ternaryfunc tp_call; */
1466         NULL,                               /* reprfunc tp_str; */
1467         NULL,                               /* getattrofunc tp_getattro; */
1468         NULL,                               /* setattrofunc tp_setattro; */
1469
1470         /* Functions to access object as input/output buffer */
1471         NULL,                               /* PyBufferProcs *tp_as_buffer; */
1472
1473   /*** Flags to define presence of optional/expanded features ***/
1474         Py_TPFLAGS_DEFAULT,                 /* long tp_flags; */
1475
1476         NULL,                               /*  char *tp_doc;  */
1477   /*** Assigned meaning in release 2.0 ***/
1478         /* call function for all accessible objects */
1479         NULL,                               /* traverseproc tp_traverse; */
1480
1481         /* delete references to contained objects */
1482         NULL,                               /* inquiry tp_clear; */
1483
1484   /***  Assigned meaning in release 2.1 ***/
1485   /*** rich comparisons ***/
1486         NULL,                               /* richcmpfunc tp_richcompare; */
1487
1488   /***  weak reference enabler ***/
1489         0,                                  /* long tp_weaklistoffset; */
1490
1491   /*** Added in release 2.2 ***/
1492         /*   Iterators */
1493         ( getiterfunc ) Curve_getIter,      /* getiterfunc tp_iter; */
1494         ( iternextfunc ) Curve_iterNext,        /* iternextfunc tp_iternext; */
1495
1496   /*** Attribute descriptor and subclassing stuff ***/
1497         BPy_Curve_methods,                  /* struct PyMethodDef *tp_methods; */
1498         NULL,                               /* struct PyMemberDef *tp_members; */
1499         Curve_getseters,                    /* struct PyGetSetDef *tp_getset; */
1500         NULL,                               /* struct _typeobject *tp_base; */
1501         NULL,                               /* PyObject *tp_dict; */
1502         NULL,                               /* descrgetfunc tp_descr_get; */
1503         NULL,                               /* descrsetfunc tp_descr_set; */
1504         0,                                  /* long tp_dictoffset; */
1505         NULL,                               /* initproc tp_init; */
1506         NULL,                               /* allocfunc tp_alloc; */
1507         NULL,                               /* newfunc tp_new; */
1508         /*  Low-level free-memory routine */
1509         NULL,                               /* freefunc tp_free;  */
1510         /* For PyObject_IS_GC */
1511         NULL,                               /* inquiry tp_is_gc;  */
1512         NULL,                               /* PyObject *tp_bases; */
1513         /* method resolution order */
1514         NULL,                               /* PyObject *tp_mro;  */
1515         NULL,                               /* PyObject *tp_cache; */
1516         NULL,                               /* PyObject *tp_subclasses; */
1517         NULL,                               /* PyObject *tp_weaklist; */
1518         NULL
1519 };
1520
1521
1522 /*****************************************************************************/
1523 /* Function:              Curve_Init                                         */
1524 /*****************************************************************************/
1525 PyObject *Curve_Init( void )
1526 {
1527         PyObject *submodule;
1528
1529         if( PyType_Ready( &Curve_Type) < 0) /* set exception.  -1 is failure */
1530                 return NULL;
1531
1532         submodule =
1533                 Py_InitModule3( "Blender.Curve", M_Curve_methods,
1534                                 M_Curve_doc );
1535         return ( submodule );
1536 }
1537
1538
1539 /*
1540  * Curve_CreatePyObject
1541  * constructor to build a py object from blender data 
1542  */
1543
1544 PyObject *Curve_CreatePyObject( struct Curve * curve )
1545 {
1546         BPy_Curve *blen_object;
1547
1548         blen_object = ( BPy_Curve * ) PyObject_NEW( BPy_Curve, &Curve_Type );
1549
1550         if( blen_object == NULL ) {
1551                 return ( NULL );
1552         }
1553         blen_object->curve = curve;
1554         return ( ( PyObject * ) blen_object );
1555
1556 }
1557
1558 struct Curve *Curve_FromPyObject( PyObject * py_obj )
1559 {
1560         BPy_Curve *blen_obj;
1561
1562         blen_obj = ( BPy_Curve * ) py_obj;
1563         return ( blen_obj->curve );
1564
1565 }
1566
1567 /* #####DEPRECATED###### */
1568
1569 PyObject *Curve_setName( BPy_Curve * self, PyObject * args )
1570 {
1571         return EXPP_setterWrapper( (void *)self, args, (setter)Curve_newsetName );
1572 }
1573
1574 static PyObject *Curve_setPathLen( BPy_Curve * self, PyObject * args )
1575 {
1576         return EXPP_setterWrapper( (void *)self, args,
1577                         (setter)Curve_newsetPathLen );
1578 }
1579
1580 static PyObject *Curve_setTotcol( BPy_Curve * self, PyObject * args )
1581 {
1582         if( !PyArg_ParseTuple( args, "i", &( self->curve->totcol ) ) )
1583                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1584                                 "expected int argument" );
1585         Py_RETURN_NONE;
1586 }
1587
1588 PyObject *Curve_setMode( BPy_Curve * self, PyObject * args )
1589 {
1590         return EXPP_setterWrapper( (void *)self, args,
1591                         (setter)Curve_newsetMode );
1592 }
1593
1594 PyObject *Curve_setBevresol( BPy_Curve * self, PyObject * args )
1595 {
1596         return EXPP_setterWrapper( (void *)self, args,
1597                         (setter)Curve_newsetBevresol);
1598 }
1599
1600 PyObject *Curve_setResolu( BPy_Curve * self, PyObject * args )
1601 {
1602         return EXPP_setterWrapper( (void *)self, args,
1603                         (setter)Curve_newsetResolu );
1604 }
1605
1606 PyObject *Curve_setResolv( BPy_Curve * self, PyObject * args )
1607 {
1608         return EXPP_setterWrapper( (void *)self, args,
1609                         (setter)Curve_newsetResolv );
1610 }
1611
1612 PyObject *Curve_setWidth( BPy_Curve * self, PyObject * args )
1613 {
1614         return EXPP_setterWrapper( (void *)self, args,
1615                         (setter)Curve_newsetWidth );
1616 }
1617
1618 PyObject *Curve_setExt1( BPy_Curve * self, PyObject * args )
1619 {
1620         return EXPP_setterWrapper( (void *)self, args,
1621                         (setter)Curve_newsetExt1 );
1622 }
1623
1624 PyObject *Curve_setExt2( BPy_Curve * self, PyObject * args )
1625 {
1626         return EXPP_setterWrapper( (void *)self, args,
1627                         (setter)Curve_newsetExt2 );
1628 }
1629
1630 static PyObject *Curve_setLoc( BPy_Curve * self, PyObject * args )
1631 {
1632         return EXPP_setterWrapper( (void *)self, args,
1633                         (setter)Curve_newsetLoc );
1634 }
1635
1636 static PyObject *Curve_setRot( BPy_Curve * self, PyObject * args )
1637 {
1638         return EXPP_setterWrapper( (void *)self, args,
1639                         (setter)Curve_newsetRot );
1640 }
1641
1642 static PyObject *Curve_setSize( BPy_Curve * self, PyObject * args )
1643 {
1644         return EXPP_setterWrapper( (void *)self, args,
1645                         (setter)Curve_newsetSize );
1646 }
1647
1648 PyObject *Curve_setBevOb( BPy_Curve * self, PyObject * args )
1649 {
1650         return EXPP_setterWrapper( (void *)self, args,
1651                         (setter)Curve_newsetBevOb );
1652 }
1653
1654 PyObject *Curve_setTaperOb( BPy_Curve * self, PyObject * args )
1655 {
1656         return EXPP_setterWrapper( (void *)self, args,
1657                         (setter)Curve_newsetTaperOb );
1658 }
1659