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