26208e600e65445b899226dc982766cae549bc2d
[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                         /* calchandlesNurb( new_nurb ); */
826                 } else {        /* set up bp */
827                         new_nurb->pntsv = 1;
828                         new_nurb->type = CU_NURBS;
829                         new_nurb->orderu = 4;
830                         new_nurb->flagu = 0;
831                         new_nurb->flagv = 0;
832                         new_nurb->bp->f1 = 0;
833                         new_nurb->bp->hide = 0;
834                         new_nurb->knotsu = 0;
835                         /*makenots( new_nurb, 1, new_nurb->flagu >> 1); */
836                 }
837                 BLI_addtail( &self->curve->nurb, new_nurb);
838
839         } else {
840                 freeNurb( new_nurb );
841                 return NULL;    /* with PyErr already set */
842         }
843
844         return CurNurb_CreatePyObject( new_nurb );
845 }
846
847
848 /* 
849  *   Curve_update( )
850  *   method to update display list for a Curve.
851  *   used. after messing with control points
852  */
853
854 PyObject *Curve_update( BPy_Curve * self )
855 {
856         Nurb *nu = self->curve->nurb.first;
857
858         /* recalculate handles for each curve: calchandlesNurb() will make
859          * sure curves are bezier first */
860         while( nu ) {
861                 calchandlesNurb ( nu );
862                 nu = nu->next;
863         }
864
865         Object_updateDag( (void*) self->curve );
866
867         Py_RETURN_NONE;
868 }
869
870 /*
871  * Curve_getMaterials
872  *
873  */
874
875 static PyObject *Curve_getMaterials( BPy_Curve * self )
876 {
877         return EXPP_PyList_fromMaterialList( self->curve->mat,
878                         self->curve->totcol, 1 );
879 }
880
881 static int Curve_setMaterials( BPy_Curve *self, PyObject * value )
882 {
883         Material **matlist;
884         int len;
885
886         if( !PySequence_Check( value ) ||
887                         !EXPP_check_sequence_consistency( value, &Material_Type ) )
888                 return EXPP_ReturnIntError( PyExc_TypeError,
889                                 "sequence should only contain materials or None)" );
890
891         len = PySequence_Size( value );
892         if( len > 16 )
893                 return EXPP_ReturnIntError( PyExc_TypeError,
894                         "list can't have more than 16 materials" );
895
896         /* free old material list (if it exists) and adjust user counts */
897         if( self->curve->mat ) {
898                 Curve *cur = self->curve;
899                 int i;
900                 for( i = cur->totcol; i-- > 0; )
901                         if( cur->mat[i] )
902                         cur->mat[i]->id.us--;
903                 MEM_freeN( cur->mat );
904         }
905
906         /* build the new material list, increment user count, store it */
907
908         matlist = EXPP_newMaterialList_fromPyList( value );
909         EXPP_incr_mats_us( matlist, len );
910         self->curve->mat = matlist;
911         self->curve->totcol = (short)len;
912
913 /**@ This is another ugly fix due to the weird material handling of blender.
914     * it makes sure that object material lists get updated (by their length)
915     * according to their data material lists, otherwise blender crashes.
916     * It just stupidly runs through all objects...BAD BAD BAD.
917     */
918
919         test_object_materials( ( ID * ) self->curve );
920
921         return 0;
922 }
923
924 /*****************************************************************************/
925 /* Function:    Curve_getBevOb                                               */
926 /* Description: Get the bevel object assign to the curve.                    */
927 /*****************************************************************************/
928 static PyObject *Curve_getBevOb( BPy_Curve * self)
929 {
930         if( self->curve->bevobj ) {
931                 return Object_CreatePyObject( self->curve->bevobj );
932         }
933
934         return EXPP_incr_ret( Py_None );
935 }
936
937 /*****************************************************************************/
938 /* Function:    Curve_newsetBevOb                                            */
939 /* Description: Assign a bevel object to the curve.                          */
940 /*****************************************************************************/
941 static int Curve_newsetBevOb( BPy_Curve * self, PyObject * args )
942 {
943         
944         if (BPy_Object_Check( args ) && ((BPy_Object *)args)->object->data == self->curve )
945                 return EXPP_ReturnIntError( PyExc_ValueError,
946                                 "Can't bevel an object to itself" );
947         
948         return GenericLib_assignData(args, (void **) &self->curve->bevobj, 0, 0, ID_OB, OB_CURVE);
949 }
950
951 /*****************************************************************************/
952 /* Function:    Curve_getTaperOb                                             */
953 /* Description: Get the taper object assign to the curve.                    */
954 /*****************************************************************************/
955
956 static PyObject *Curve_getTaperOb( BPy_Curve * self)
957 {
958         if( self->curve->taperobj )
959                 return Object_CreatePyObject( self->curve->taperobj );
960
961         Py_RETURN_NONE;
962 }
963
964 /*****************************************************************************/
965 /* Function:    Curve_newsetTaperOb                                          */
966 /* Description: Assign a taper object to the curve.                          */
967 /*****************************************************************************/
968
969 static int Curve_newsetTaperOb( BPy_Curve * self, PyObject * args )
970 {
971         if (BPy_Object_Check( args ) && ((BPy_Object *)args)->object->data == self->curve )
972                 return EXPP_ReturnIntError( PyExc_ValueError,
973                                 "Can't taper an object to itself" );
974         
975         return GenericLib_assignData(args, (void **) &self->curve->taperobj, 0, 0, ID_OB, OB_CURVE);
976 }
977
978 /*****************************************************************************/
979 /* Function:    Curve_copy                                                   */
980 /* Description: Return a copy of this curve data.                            */
981 /*****************************************************************************/
982
983 PyObject *Curve_copy( BPy_Curve * self )
984 {
985         BPy_Curve *pycurve;     /* for Curve Data object wrapper in Python */
986         Curve *blcurve = 0;     /* for actual Curve Data we create in Blender */
987
988         /* copies the data */
989         blcurve = copy_curve( self->curve );    /* first create the Curve Data in Blender */
990
991         if( blcurve == NULL )   /* bail out if add_curve() failed */
992                 return ( EXPP_ReturnPyObjError
993                          ( PyExc_RuntimeError,
994                            "couldn't create Curve Data in Blender" ) );
995
996         /* return user count to zero because add_curve() inc'd it */
997         blcurve->id.us = 0;
998         
999         /* create python wrapper obj */
1000         pycurve = ( BPy_Curve * ) PyObject_NEW( BPy_Curve, &Curve_Type );
1001
1002         if( pycurve == NULL )
1003                 return ( EXPP_ReturnPyObjError
1004                          ( PyExc_MemoryError,
1005                            "couldn't create Curve Data object" ) );
1006
1007         pycurve->curve = blcurve;       /* link Python curve wrapper to Blender Curve */
1008         return ( PyObject * ) pycurve;
1009 }
1010
1011
1012 /*
1013  * Curve_getIter
1014  *
1015  * create an iterator for our Curve.
1016  * this iterator returns the Nurbs for this Curve.
1017  * the iter_pointer always points to the next available item or null
1018  */
1019
1020 static PyObject *Curve_getIter( BPy_Curve * self )
1021 {
1022         self->iter_pointer = self->curve->nurb.first;
1023
1024         Py_INCREF( self );
1025         return ( PyObject * ) self;
1026
1027 }
1028
1029
1030 /*
1031  * Curve_iterNext
1032  *  get the next item.
1033  *  iter_pointer always points to the next available element
1034  *   or NULL if at the end of the list.
1035  */
1036
1037 static PyObject *Curve_iterNext( BPy_Curve * self )
1038 {
1039         Nurb *pnurb;
1040
1041         if( self->iter_pointer ) {
1042                 pnurb = self->iter_pointer;
1043                 self->iter_pointer = pnurb->next;       /* advance iterator */
1044                 if( (pnurb->type & 7) == CU_BEZIER || pnurb->pntsv <= 1 )
1045                         return CurNurb_CreatePyObject( pnurb ); /* make a bpy_curnurb */
1046                 else
1047                         return SurfNurb_CreatePyObject( pnurb ); /* make a bpy_surfnurb */
1048         }
1049
1050         /* if iter_pointer was null, we are at end */
1051         return EXPP_ReturnPyObjError( PyExc_StopIteration,
1052                         "iterator at end" );
1053 }
1054
1055 /* tp_sequence methods */
1056
1057 /*
1058  * Curve_length
1059  * returns the number of curves in a Curve
1060  * this is a tp_as_sequence method, not a regular instance method.
1061  */
1062
1063 static int Curve_length( PyInstanceObject * inst )
1064 {
1065         if( BPy_Curve_Check( ( PyObject * ) inst ) )
1066                 return ( ( int ) PyInt_AsLong
1067                          ( Curve_getNumCurves( ( BPy_Curve * ) inst ) ) );
1068
1069         return EXPP_ReturnIntError( PyExc_RuntimeError,
1070                                     "arg is not a BPy_Curve" );
1071
1072 }
1073
1074 /*
1075  * Curve_getNurb
1076  * returns the Nth nurb in a Curve.
1077  * this is one of the tp_as_sequence methods, hence the int N argument.
1078  * it is called via the [] operator, not as a usual instance method.
1079  */
1080
1081 PyObject *Curve_getNurb( BPy_Curve * self, int n )
1082 {
1083         Nurb *pNurb;
1084         int i;
1085
1086         /* bail if index < 0 */
1087         if( n < 0 )
1088                 return ( EXPP_ReturnPyObjError( PyExc_IndexError,
1089                                                 "index less than 0" ) );
1090         /* bail if no Nurbs in Curve */
1091         if( self->curve->nurb.first == 0 )
1092                 return ( EXPP_ReturnPyObjError( PyExc_IndexError,
1093                                                 "no Nurbs in this Curve" ) );
1094         /* set pointer to nth Nurb */
1095         for( pNurb = self->curve->nurb.first, i = 0;
1096              pNurb != 0 && i < n; pNurb = pNurb->next, ++i )
1097                 /**/;
1098
1099         if( !pNurb )            /* we came to the end of the list */
1100                 return ( EXPP_ReturnPyObjError( PyExc_IndexError,
1101                                                 "index out of range" ) );
1102
1103         /* until there is a Surface BPyType, distinquish between a curve and a
1104          * surface based on whether it's a Bezier and the v size */
1105         if( (pNurb->type & 7) == CU_BEZIER || pNurb->pntsv <= 1 )
1106                 return CurNurb_CreatePyObject( pNurb ); /* make a bpy_curnurb */
1107         else
1108                 return SurfNurb_CreatePyObject( pNurb );        /* make a bpy_surfnurb */
1109
1110 }
1111
1112 /*
1113  * Curve_setNurb
1114  * In this case only remove the item, we could allow adding later.
1115  */
1116 static int Curve_setNurb( BPy_Curve * self, int n, PyObject * value )
1117 {
1118         Nurb *pNurb;
1119         int i;
1120
1121         /* bail if index < 0 */
1122         if( n < 0 )
1123                 return ( EXPP_ReturnIntError( PyExc_IndexError,
1124                                  "index less than 0" ) );
1125         /* bail if no Nurbs in Curve */
1126         if( self->curve->nurb.first == 0 )
1127                 return ( EXPP_ReturnIntError( PyExc_IndexError,
1128                                  "no Nurbs in this Curve" ) );
1129         /* set pointer to nth Nurb */
1130         for( pNurb = self->curve->nurb.first, i = 0;
1131                         pNurb != 0 && i < n; pNurb = pNurb->next, ++i )
1132                 /**/;
1133
1134         if( !pNurb )            /* we came to the end of the list */
1135                 return ( EXPP_ReturnIntError( PyExc_IndexError,
1136                                  "index out of range" ) );
1137         
1138         if (value) {
1139                 return ( EXPP_ReturnIntError( PyExc_RuntimeError,
1140                                  "assigning curves is not yet supported" ) );
1141         } else {
1142                 BLI_remlink(&self->curve->nurb, pNurb);
1143                 freeNurb(pNurb);
1144         }
1145         return 0;
1146 }
1147
1148 /*****************************************************************************/
1149 /* Function:    Curve_compare                                                    */
1150 /* Description: This compares 2 curve python types, == or != only.                       */
1151 /*****************************************************************************/
1152 static int Curve_compare( BPy_Curve * a, BPy_Curve * b )
1153 {
1154         return ( a->curve == b->curve ) ? 0 : -1;
1155 }
1156
1157 /*****************************************************************************/
1158 /* Function:    Curve_repr                                                   */
1159 /* Description: This is a callback function for the BPy_Curve type. It       */
1160 /*              builds a meaninful string to represent curve objects.        */
1161 /*****************************************************************************/
1162 static PyObject *Curve_repr( BPy_Curve * self )
1163 {                               /* used by 'repr' */
1164
1165         return PyString_FromFormat( "[Curve \"%s\"]",
1166                                     self->curve->id.name + 2 );
1167 }
1168
1169 /* attributes for curves */
1170
1171 static PyGetSetDef Curve_getseters[] = {
1172         GENERIC_LIB_GETSETATTR,
1173         {"pathlen",
1174          (getter)Curve_getPathLen, (setter)Curve_newsetPathLen,
1175          "The path length,  used to set the number of frames for an animation (not the physical length)",
1176         NULL},
1177         {"totcol",
1178          (getter)Curve_getTotcol, (setter)NULL,
1179          "The maximum number of linked materials",
1180         NULL},
1181         {"flag",
1182          (getter)Curve_getMode, (setter)Curve_newsetMode,
1183          "The flag bitmask",
1184         NULL},
1185         {"bevresol",
1186          (getter)Curve_getBevresol, (setter)Curve_newsetBevresol,
1187          "The bevel resolution",
1188         NULL},
1189         {"resolu",
1190          (getter)Curve_getResolu, (setter)Curve_newsetResolu,
1191          "The resolution in U direction",
1192         NULL},
1193         {"resolv",
1194          (getter)Curve_getResolv, (setter)Curve_newsetResolv,
1195          "The resolution in V direction",
1196         NULL},
1197         {"width",
1198          (getter)Curve_getWidth, (setter)Curve_newsetWidth,
1199          "The curve width",
1200         NULL},
1201         {"ext1",
1202          (getter)Curve_getExt1, (setter)Curve_newsetExt1,
1203          "The extent1 value (for bevels)",
1204         NULL},
1205         {"ext2",
1206          (getter)Curve_getExt2, (setter)Curve_newsetExt2,
1207          "The extent2 value (for bevels)",
1208         NULL},
1209         {"loc",
1210          (getter)Curve_getLoc, (setter)Curve_newsetLoc,
1211          "The data location (from the center)",
1212         NULL},
1213         {"rot",
1214          (getter)Curve_getRot, (setter)Curve_newsetRot,
1215          "The data rotation (from the center)",
1216         NULL},
1217         {"size",
1218          (getter)Curve_getSize, (setter)Curve_newsetSize,
1219          "The data size (from the center)",
1220         NULL},
1221         {"bevob",
1222          (getter)Curve_getBevOb, (setter)Curve_newsetBevOb,
1223          "The bevel object",
1224         NULL},
1225         {"taperob",
1226          (getter)Curve_getTaperOb, (setter)Curve_newsetTaperOb,
1227          "The taper object",
1228         NULL},
1229         {"key",
1230          (getter)Curve_getKey, (setter)NULL,
1231          "The shape key for the curve (if any)",
1232         NULL},
1233         {"materials",
1234          (getter)Curve_getMaterials, (setter)Curve_setMaterials,
1235          "The materials associated with the curve",
1236         NULL},
1237         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
1238
1239 };
1240
1241 /*****************************************************************************/
1242 /* Function:              M_Curve_New                                       */
1243 /* Python equivalent:     Blender.Curve.New                                 */
1244 /*****************************************************************************/
1245 static PyObject *M_Curve_New( PyObject * self, PyObject * args )
1246 {
1247         char *name = "Curve";
1248         BPy_Curve *pycurve;     /* for Curve Data object wrapper in Python */
1249         Curve *blcurve = 0;     /* for actual Curve Data we create in Blender */
1250
1251         if( !PyArg_ParseTuple( args, "|s", &name ) )
1252                 return ( EXPP_ReturnPyObjError
1253                          ( PyExc_TypeError,
1254                            "expected string argument or no argument" ) );
1255
1256         blcurve = add_curve( name, OB_CURVE );  /* first create the Curve Data in Blender */
1257
1258         if( blcurve == NULL )   /* bail out if add_curve() failed */
1259                 return ( EXPP_ReturnPyObjError
1260                          ( PyExc_RuntimeError,
1261                            "couldn't create Curve Data in Blender" ) );
1262
1263         /* return user count to zero because add_curve() inc'd it */
1264         blcurve->id.us = 0;
1265         /* create python wrapper obj */
1266         pycurve = ( BPy_Curve * ) PyObject_NEW( BPy_Curve, &Curve_Type );
1267
1268         if( pycurve == NULL )
1269                 return ( EXPP_ReturnPyObjError
1270                          ( PyExc_MemoryError,
1271                            "couldn't create Curve Data object" ) );
1272
1273         pycurve->curve = blcurve;       /* link Python curve wrapper to Blender Curve */
1274         
1275         return ( PyObject * ) pycurve;
1276 }
1277
1278 /*****************************************************************************/
1279 /* Function:              M_Curve_Get                                       */
1280 /* Python equivalent:     Blender.Curve.Get                                 */
1281 /*****************************************************************************/
1282 static PyObject *M_Curve_Get( PyObject * self, PyObject * args )
1283 {
1284
1285         char *name = NULL;
1286         Curve *curv_iter;
1287         BPy_Curve *wanted_curv;
1288
1289         if( !PyArg_ParseTuple( args, "|s", &name ) )    /* expects nothing or a string */
1290                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1291                                                 "expected string argument" ) );
1292         if( name ) {            /*a name has been given */
1293                 /* Use the name to search for the curve requested */
1294                 wanted_curv = NULL;
1295                 curv_iter = G.main->curve.first;
1296
1297                 while( ( curv_iter ) && ( wanted_curv == NULL ) ) {
1298
1299                         if( strcmp( name, curv_iter->id.name + 2 ) == 0 ) {
1300                                 wanted_curv = ( BPy_Curve * )
1301                                         PyObject_NEW( BPy_Curve, &Curve_Type );
1302                                 if( wanted_curv )
1303                                         wanted_curv->curve = curv_iter;
1304                         }
1305
1306                         curv_iter = curv_iter->id.next;
1307                 }
1308
1309                 if( wanted_curv == NULL ) {     /* Requested curve doesn't exist */
1310                         char error_msg[64];
1311                         PyOS_snprintf( error_msg, sizeof( error_msg ),
1312                                        "Curve \"%s\" not found", name );
1313                         return ( EXPP_ReturnPyObjError
1314                                  ( PyExc_NameError, error_msg ) );
1315                 }
1316
1317
1318                 return ( PyObject * ) wanted_curv;
1319         } /* end  of if(name) */
1320         else {
1321                 /* no name has been given; return a list of all curves by name.  */
1322                 PyObject *curvlist;
1323
1324                 curv_iter = G.main->curve.first;
1325                 curvlist = PyList_New( 0 );
1326
1327                 if( curvlist == NULL )
1328                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
1329                                                         "couldn't create PyList" ) );
1330
1331                 while( curv_iter ) {
1332                         BPy_Curve *found_cur =
1333                                 ( BPy_Curve * ) PyObject_NEW( BPy_Curve,
1334                                                               &Curve_Type );
1335                         found_cur->curve = curv_iter;
1336                         PyList_Append( curvlist, ( PyObject * ) found_cur );
1337                         Py_DECREF(found_cur);
1338                         curv_iter = curv_iter->id.next;
1339                 }
1340
1341                 return ( curvlist );
1342         }                       /* end of else */
1343 }
1344
1345 /*****************************************************************************/
1346 /*  Python method definitions for Blender.Curve module:             */
1347 /*****************************************************************************/
1348 struct PyMethodDef M_Curve_methods[] = {
1349         {"New", ( PyCFunction ) M_Curve_New, METH_VARARGS, M_Curve_New_doc},
1350         {"Get", M_Curve_Get, METH_VARARGS, M_Curve_Get_doc},
1351         {"get", M_Curve_Get, METH_VARARGS, M_Curve_Get_doc},
1352         {NULL, NULL, 0, NULL}
1353 };
1354
1355
1356 /*****************************************************************************/
1357 /*  Python BPy_Curve instance methods table:                                 */
1358 /*****************************************************************************/
1359 static PyMethodDef BPy_Curve_methods[] = {
1360         {"getName", ( PyCFunction ) Curve_getName,
1361          METH_NOARGS, "() - Return Curve Data name"},
1362         {"setName", ( PyCFunction ) Curve_setName,
1363          METH_VARARGS, "() - Sets Curve Data name"},
1364         {"getPathLen", ( PyCFunction ) Curve_getPathLen,
1365          METH_NOARGS, "() - Return Curve path length"},
1366         {"setPathLen", ( PyCFunction ) Curve_setPathLen,
1367          METH_VARARGS, "(int) - Sets Curve path length"},
1368         {"getTotcol", ( PyCFunction ) Curve_getTotcol,
1369          METH_NOARGS, "() - Return the number of materials of the curve"},
1370         {"setTotcol", ( PyCFunction ) Curve_setTotcol,
1371          METH_VARARGS, "(int) - Sets the number of materials of the curve"},
1372         {"getFlag", ( PyCFunction ) Curve_getMode,
1373          METH_NOARGS, "() - Return flag (see the doc for semantic)"},
1374         {"setFlag", ( PyCFunction ) Curve_setMode,
1375          METH_VARARGS, "(int) - Sets flag (see the doc for semantic)"},
1376         {"getBevresol", ( PyCFunction ) Curve_getBevresol,
1377          METH_NOARGS, "() - Return bevel resolution"},
1378         {"setBevresol", ( PyCFunction ) Curve_setBevresol,
1379          METH_VARARGS, "(int) - Sets bevel resolution"},
1380         {"getResolu", ( PyCFunction ) Curve_getResolu,
1381          METH_NOARGS, "() - Return U resolution"},
1382         {"setResolu", ( PyCFunction ) Curve_setResolu,
1383          METH_VARARGS, "(int) - Sets U resolution"},
1384         {"getResolv", ( PyCFunction ) Curve_getResolv,
1385          METH_NOARGS, "() - Return V resolution"},
1386         {"setResolv", ( PyCFunction ) Curve_setResolv,
1387          METH_VARARGS, "(int) - Sets V resolution"},
1388         {"getWidth", ( PyCFunction ) Curve_getWidth,
1389          METH_NOARGS, "() - Return curve width"},
1390         {"setWidth", ( PyCFunction ) Curve_setWidth,
1391          METH_VARARGS, "(int) - Sets curve width"},
1392         {"getExt1", ( PyCFunction ) Curve_getExt1,
1393          METH_NOARGS, "() - Returns extent 1 of the bevel"},
1394         {"setExt1", ( PyCFunction ) Curve_setExt1,
1395          METH_VARARGS, "(int) - Sets  extent 1 of the bevel"},
1396         {"getExt2", ( PyCFunction ) Curve_getExt2,
1397          METH_NOARGS, "() - Return extent 2 of the bevel "},
1398         {"setExt2", ( PyCFunction ) Curve_setExt2,
1399          METH_VARARGS, "(int) - Sets extent 2 of the bevel "},
1400         {"getControlPoint", ( PyCFunction ) Curve_getControlPoint,
1401          METH_VARARGS, "(int numcurve,int numpoint) -\
1402 Gets a control point.Depending upon the curve type, returne a list of 4 or 9 floats"},
1403         {"setControlPoint", ( PyCFunction ) Curve_setControlPoint,
1404          METH_VARARGS, "(int numcurve,int numpoint,float x,float y,float z,\
1405 float w)(nurbs) or  (int numcurve,int numpoint,float x1,...,x9(bezier)\
1406 Sets a control point "},
1407         {"getLoc", ( PyCFunction ) Curve_getLoc,
1408          METH_NOARGS, "() - Gets Location of the curve (a 3-tuple) "},
1409         {"setLoc", ( PyCFunction ) Curve_setLoc,
1410          METH_VARARGS, "(3-tuple) - Sets Location "},
1411         {"getRot", ( PyCFunction ) Curve_getRot,
1412          METH_NOARGS, "() - Gets curve rotation"},
1413         {"setRot", ( PyCFunction ) Curve_setRot,
1414          METH_VARARGS, "(3-tuple) - Sets curve rotation"},
1415         {"getSize", ( PyCFunction ) Curve_getSize,
1416          METH_NOARGS, "() - Gets curve size"},
1417         {"setSize", ( PyCFunction ) Curve_setSize,
1418          METH_VARARGS, "(3-tuple) - Sets curve size"},
1419         {"getNumCurves", ( PyCFunction ) Curve_getNumCurves,
1420          METH_NOARGS, "() - Gets number of curves in Curve"},
1421         {"getKey", ( PyCFunction ) Curve_getKey,
1422          METH_NOARGS, "() - Gets curve key"},
1423         {"isNurb", ( PyCFunction ) Curve_isNurb,
1424          METH_VARARGS,
1425          "(nothing or integer) - returns 1 if curve is type Nurb, O otherwise."},
1426         {"isCyclic", ( PyCFunction ) Curve_isCyclic,
1427          METH_VARARGS, "( nothing or integer ) - returns true if curve is cyclic (closed), false otherwise."},
1428         {"getNumPoints", ( PyCFunction ) Curve_getNumPoints,
1429          METH_VARARGS,
1430          "(nothing or integer) - returns the number of points of the specified curve"},
1431         {"appendPoint", ( PyCFunction ) Curve_appendPoint, METH_VARARGS,
1432          "( int numcurve, list of coordinates) - adds a new point to end of curve"},
1433         {"appendNurb", ( PyCFunction ) Curve_appendNurb, METH_O,
1434          "( new_nurb ) - adds a new nurb to the Curve"},
1435         {"update", ( PyCFunction ) Curve_update, METH_NOARGS,
1436          "( ) - updates display lists after changes to Curve"},
1437         {"getMaterials", ( PyCFunction ) Curve_getMaterials, METH_NOARGS,
1438          "() - returns list of materials assigned to this Curve"},
1439         {"getBevOb", ( PyCFunction ) Curve_getBevOb, METH_NOARGS,
1440          "() - returns Bevel Object assigned to this Curve"},
1441         {"setBevOb", ( PyCFunction ) Curve_setBevOb, METH_VARARGS,
1442          "() - assign a Bevel Object to this Curve"},
1443         {"getTaperOb", ( PyCFunction ) Curve_getTaperOb, METH_NOARGS,
1444          "() - returns Taper Object assigned to this Curve"},
1445         {"setTaperOb", ( PyCFunction ) Curve_setTaperOb, METH_VARARGS,
1446          "() - assign a Taper Object to this Curve"},
1447         {"__copy__", ( PyCFunction ) Curve_copy, METH_NOARGS,
1448          "() - make a copy of this curve data"},
1449         {"copy", ( PyCFunction ) Curve_copy, METH_NOARGS,
1450          "() - make a copy of this curve data"},
1451         {NULL, NULL, 0, NULL}
1452 };
1453
1454
1455 /*****************************************************************************/
1456 /*  Python Curve_Type callback function prototypes:                         */
1457 /*****************************************************************************/
1458 static int Curve_compare( BPy_Curve * a, BPy_Curve * b );
1459 static PyObject *Curve_repr( BPy_Curve * msh );
1460
1461 static PySequenceMethods Curve_as_sequence = {
1462         ( inquiry ) Curve_length,       /* sq_length   */
1463         ( binaryfunc ) 0,       /* sq_concat */
1464         ( intargfunc ) 0,       /* sq_repeat */
1465         ( intargfunc ) Curve_getNurb,   /* sq_item */
1466         ( intintargfunc ) 0,    /* sq_slice */
1467         ( intobjargproc ) Curve_setNurb,        /* sq_ass_item - only so you can do del curve[i] */
1468         0,                      /* sq_ass_slice */
1469         ( objobjproc ) 0,       /* sq_contains */
1470         0,
1471         0
1472 };
1473
1474 /*****************************************************************************/
1475 /* Python Curve_Type structure definition:                                   */
1476 /*****************************************************************************/
1477 PyTypeObject Curve_Type = {
1478         PyObject_HEAD_INIT( NULL )          /* required macro */ 
1479         0,                                  /* ob_size */
1480         "Curve",                            /* tp_name */
1481         sizeof( BPy_Curve ),                /* tp_basicsize */
1482         0,                                  /* tp_itemsize */
1483         /* methods */
1484         NULL,                                                           /* tp_dealloc */
1485         0,                                  /* tp_print */
1486         ( getattrfunc ) NULL,               /* tp_getattr */
1487         ( setattrfunc ) NULL,               /* tp_setattr */
1488         ( cmpfunc ) Curve_compare,          /* tp_compare */
1489         ( reprfunc ) Curve_repr,            /* tp_repr */
1490         /* Method suites for standard classes */
1491
1492         NULL,                               /* PyNumberMethods *tp_as_number; */
1493         &Curve_as_sequence,                 /* PySequenceMethods *tp_as_sequence; */
1494         NULL,                               /* PyMappingMethods *tp_as_mapping; */
1495
1496         /* More standard operations (here for binary compatibility) */
1497
1498         ( hashfunc ) GenericLib_hash,           /* hashfunc tp_hash; */
1499         NULL,                               /* ternaryfunc tp_call; */
1500         NULL,                               /* reprfunc tp_str; */
1501         NULL,                               /* getattrofunc tp_getattro; */
1502         NULL,                               /* setattrofunc tp_setattro; */
1503
1504         /* Functions to access object as input/output buffer */
1505         NULL,                               /* PyBufferProcs *tp_as_buffer; */
1506
1507   /*** Flags to define presence of optional/expanded features ***/
1508         Py_TPFLAGS_DEFAULT,                 /* long tp_flags; */
1509
1510         NULL,                               /*  char *tp_doc;  */
1511   /*** Assigned meaning in release 2.0 ***/
1512         /* call function for all accessible objects */
1513         NULL,                               /* traverseproc tp_traverse; */
1514
1515         /* delete references to contained objects */
1516         NULL,                               /* inquiry tp_clear; */
1517
1518   /***  Assigned meaning in release 2.1 ***/
1519   /*** rich comparisons ***/
1520         NULL,                               /* richcmpfunc tp_richcompare; */
1521
1522   /***  weak reference enabler ***/
1523         0,                                  /* long tp_weaklistoffset; */
1524
1525   /*** Added in release 2.2 ***/
1526         /*   Iterators */
1527         ( getiterfunc ) Curve_getIter,      /* getiterfunc tp_iter; */
1528         ( iternextfunc ) Curve_iterNext,        /* iternextfunc tp_iternext; */
1529
1530   /*** Attribute descriptor and subclassing stuff ***/
1531         BPy_Curve_methods,                  /* struct PyMethodDef *tp_methods; */
1532         NULL,                               /* struct PyMemberDef *tp_members; */
1533         Curve_getseters,                    /* struct PyGetSetDef *tp_getset; */
1534         NULL,                               /* struct _typeobject *tp_base; */
1535         NULL,                               /* PyObject *tp_dict; */
1536         NULL,                               /* descrgetfunc tp_descr_get; */
1537         NULL,                               /* descrsetfunc tp_descr_set; */
1538         0,                                  /* long tp_dictoffset; */
1539         NULL,                               /* initproc tp_init; */
1540         NULL,                               /* allocfunc tp_alloc; */
1541         NULL,                               /* newfunc tp_new; */
1542         /*  Low-level free-memory routine */
1543         NULL,                               /* freefunc tp_free;  */
1544         /* For PyObject_IS_GC */
1545         NULL,                               /* inquiry tp_is_gc;  */
1546         NULL,                               /* PyObject *tp_bases; */
1547         /* method resolution order */
1548         NULL,                               /* PyObject *tp_mro;  */
1549         NULL,                               /* PyObject *tp_cache; */
1550         NULL,                               /* PyObject *tp_subclasses; */
1551         NULL,                               /* PyObject *tp_weaklist; */
1552         NULL
1553 };
1554
1555
1556 /*****************************************************************************/
1557 /* Function:              Curve_Init                                         */
1558 /*****************************************************************************/
1559 PyObject *Curve_Init( void )
1560 {
1561         PyObject *submodule;
1562
1563         if( PyType_Ready( &Curve_Type) < 0) /* set exception.  -1 is failure */
1564                 return NULL;
1565
1566         submodule =
1567                 Py_InitModule3( "Blender.Curve", M_Curve_methods,
1568                                 M_Curve_doc );
1569         return ( submodule );
1570 }
1571
1572
1573 /*
1574  * Curve_CreatePyObject
1575  * constructor to build a py object from blender data 
1576  */
1577
1578 PyObject *Curve_CreatePyObject( struct Curve * curve )
1579 {
1580         BPy_Curve *blen_object;
1581
1582         blen_object = ( BPy_Curve * ) PyObject_NEW( BPy_Curve, &Curve_Type );
1583
1584         if( blen_object == NULL ) {
1585                 return ( NULL );
1586         }
1587         blen_object->curve = curve;
1588         return ( ( PyObject * ) blen_object );
1589
1590 }
1591
1592 struct Curve *Curve_FromPyObject( PyObject * py_obj )
1593 {
1594         BPy_Curve *blen_obj;
1595
1596         blen_obj = ( BPy_Curve * ) py_obj;
1597         return ( blen_obj->curve );
1598
1599 }
1600
1601 /* #####DEPRECATED###### */
1602
1603 PyObject *Curve_setName( BPy_Curve * self, PyObject * args )
1604 {
1605         return EXPP_setterWrapper( (void *)self, args, (setter)Curve_newsetName );
1606 }
1607
1608 static PyObject *Curve_setPathLen( BPy_Curve * self, PyObject * args )
1609 {
1610         return EXPP_setterWrapper( (void *)self, args,
1611                         (setter)Curve_newsetPathLen );
1612 }
1613
1614 static PyObject *Curve_setTotcol( BPy_Curve * self, PyObject * args )
1615 {
1616         if( !PyArg_ParseTuple( args, "i", &( self->curve->totcol ) ) )
1617                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1618                                 "expected int argument" );
1619         Py_RETURN_NONE;
1620 }
1621
1622 PyObject *Curve_setMode( BPy_Curve * self, PyObject * args )
1623 {
1624         return EXPP_setterWrapper( (void *)self, args,
1625                         (setter)Curve_newsetMode );
1626 }
1627
1628 PyObject *Curve_setBevresol( BPy_Curve * self, PyObject * args )
1629 {
1630         return EXPP_setterWrapper( (void *)self, args,
1631                         (setter)Curve_newsetBevresol);
1632 }
1633
1634 PyObject *Curve_setResolu( BPy_Curve * self, PyObject * args )
1635 {
1636         return EXPP_setterWrapper( (void *)self, args,
1637                         (setter)Curve_newsetResolu );
1638 }
1639
1640 PyObject *Curve_setResolv( BPy_Curve * self, PyObject * args )
1641 {
1642         return EXPP_setterWrapper( (void *)self, args,
1643                         (setter)Curve_newsetResolv );
1644 }
1645
1646 PyObject *Curve_setWidth( BPy_Curve * self, PyObject * args )
1647 {
1648         return EXPP_setterWrapper( (void *)self, args,
1649                         (setter)Curve_newsetWidth );
1650 }
1651
1652 PyObject *Curve_setExt1( BPy_Curve * self, PyObject * args )
1653 {
1654         return EXPP_setterWrapper( (void *)self, args,
1655                         (setter)Curve_newsetExt1 );
1656 }
1657
1658 PyObject *Curve_setExt2( BPy_Curve * self, PyObject * args )
1659 {
1660         return EXPP_setterWrapper( (void *)self, args,
1661                         (setter)Curve_newsetExt2 );
1662 }
1663
1664 static PyObject *Curve_setLoc( BPy_Curve * self, PyObject * args )
1665 {
1666         return EXPP_setterWrapper( (void *)self, args,
1667                         (setter)Curve_newsetLoc );
1668 }
1669
1670 static PyObject *Curve_setRot( BPy_Curve * self, PyObject * args )
1671 {
1672         return EXPP_setterWrapper( (void *)self, args,
1673                         (setter)Curve_newsetRot );
1674 }
1675
1676 static PyObject *Curve_setSize( BPy_Curve * self, PyObject * args )
1677 {
1678         return EXPP_setterWrapper( (void *)self, args,
1679                         (setter)Curve_newsetSize );
1680 }
1681
1682 PyObject *Curve_setBevOb( BPy_Curve * self, PyObject * args )
1683 {
1684         return EXPP_setterWrapper( (void *)self, args,
1685                         (setter)Curve_newsetBevOb );
1686 }
1687
1688 PyObject *Curve_setTaperOb( BPy_Curve * self, PyObject * args )
1689 {
1690         return EXPP_setterWrapper( (void *)self, args,
1691                         (setter)Curve_newsetTaperOb );
1692 }
1693