PyAPI - *.insertkey()
[blender.git] / source / blender / python / api2_2x / Camera.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): Willian P. Germano, Johnny Matthews, Ken Hughes
26  *
27  * ***** END GPL LICENSE BLOCK *****
28 */
29
30 #include "Camera.h" /*This must come first */
31
32 #include "BKE_main.h"
33 #include "BKE_global.h"
34 #include "BKE_object.h"
35 #include "BKE_library.h"
36 #include "BKE_utildefines.h"
37 #include "BLI_blenlib.h"
38 #include "BLI_arithb.h" /* for M_PI */
39 #include "DNA_userdef_types.h"
40 #include "BSE_editipo.h"
41 #include "BIF_keyframing.h"
42 #include "BIF_space.h"
43 #include "mydevice.h"
44 #include "gen_utils.h"
45 #include "gen_library.h"
46 #include "Ipo.h"
47
48
49 #define IPOKEY_LENS 0
50 #define IPOKEY_CLIPPING 1
51
52
53
54 enum cam_consts {
55         EXPP_CAM_ATTR_LENS = 0,
56         EXPP_CAM_ATTR_ANGLE,
57         EXPP_CAM_ATTR_DOFDIST,
58         EXPP_CAM_ATTR_CLIPEND,
59         EXPP_CAM_ATTR_CLIPSTART,
60         EXPP_CAM_ATTR_SCALE,
61         EXPP_CAM_ATTR_DRAWSIZE,
62         EXPP_CAM_ATTR_SHIFTX,
63         EXPP_CAM_ATTR_SHIFTY,
64         EXPP_CAM_ATTR_ALPHA,
65 };
66
67 /*****************************************************************************/
68 /* Python API function prototypes for the Camera module.                     */
69 /*****************************************************************************/
70 static PyObject *M_Camera_New( PyObject * self, PyObject * args,
71                                PyObject * keywords );
72 static PyObject *M_Camera_Get( PyObject * self, PyObject * args );
73
74 /*****************************************************************************/
75 /* The following string definitions are used for documentation strings.      */
76 /* In Python these will be written to the console when doing a               */
77 /* Blender.Camera.__doc__                                                    */
78 /*****************************************************************************/
79 static char M_Camera_doc[] = "The Blender Camera module\n\
80 \n\
81 This module provides access to **Camera Data** objects in Blender\n\
82 \n\
83 Example::\n\
84 \n\
85   from Blender import Camera, Object, Scene\n\
86   c = Camera.New('ortho')      # create new ortho camera data\n\
87   c.scale = 6.0                # set scale value\n\
88   scn = Scene.GetCurrent()     # get current Scene\n\
89   ob = scn.objects.new(c)      # Make an object from this data in the scene\n\
90   cur.setCurrentCamera(ob)     # make this camera the active";
91
92 static char M_Camera_New_doc[] =
93         "Camera.New (type = 'persp', name = 'CamData'):\n\
94         Return a new Camera Data object with the given type and name.";
95
96 static char M_Camera_Get_doc[] = "Camera.Get (name = None):\n\
97         Return the camera data with the given 'name', None if not found, or\n\
98         Return a list with all Camera Data objects in the current scene,\n\
99         if no argument was given.";
100
101 /*****************************************************************************/
102 /* Python method structure definition for Blender.Camera module:             */
103 /*****************************************************************************/
104 struct PyMethodDef M_Camera_methods[] = {
105         {"New", ( PyCFunction ) M_Camera_New, METH_VARARGS | METH_KEYWORDS,
106          M_Camera_New_doc},
107         {"Get", M_Camera_Get, METH_VARARGS, M_Camera_Get_doc},
108         {"get", M_Camera_Get, METH_VARARGS, M_Camera_Get_doc},
109         {NULL, NULL, 0, NULL}
110 };
111
112 /*****************************************************************************/
113 /* Python BPy_Camera methods declarations:                                   */
114 /*****************************************************************************/
115 static PyObject *Camera_oldgetType( BPy_Camera * self );
116 static PyObject *Camera_oldgetMode( BPy_Camera * self );
117 static PyObject *Camera_oldgetLens( BPy_Camera * self );
118 static PyObject *Camera_oldgetClipStart( BPy_Camera * self );
119 static PyObject *Camera_oldgetClipEnd( BPy_Camera * self );
120 static PyObject *Camera_oldgetDrawSize( BPy_Camera * self );
121 static PyObject *Camera_oldgetScale( BPy_Camera * self );
122 static PyObject *Camera_getIpo( BPy_Camera * self );
123 static int Camera_setIpo( BPy_Camera * self, PyObject * value );
124 static PyObject *Camera_oldsetIpo( BPy_Camera * self, PyObject * args );
125 static PyObject *Camera_oldsetType( BPy_Camera * self, PyObject * args );
126 static PyObject *Camera_oldsetMode( BPy_Camera * self, PyObject * args );
127 static PyObject *Camera_oldsetLens( BPy_Camera * self, PyObject * args );
128 static PyObject *Camera_oldsetClipStart( BPy_Camera * self, PyObject * args );
129 static PyObject *Camera_oldsetClipEnd( BPy_Camera * self, PyObject * args );
130 static PyObject *Camera_oldsetDrawSize( BPy_Camera * self, PyObject * args );
131 static PyObject *Camera_oldsetScale( BPy_Camera * self, PyObject * args );
132 static PyObject *Camera_oldgetScriptLinks( BPy_Camera * self, PyObject * value );
133 static PyObject *Camera_addScriptLink( BPy_Camera * self, PyObject * args );
134 static PyObject *Camera_oldclearIpo( BPy_Camera * self );
135 static PyObject *Camera_clearScriptLinks( BPy_Camera * self, PyObject * args );
136 static PyObject *Camera_insertIpoKey( BPy_Camera * self, PyObject * args );
137 static PyObject *Camera_copy( BPy_Camera * self );
138
139
140 /*****************************************************************************/
141 /* Python BPy_Camera methods table:                                          */
142 /*****************************************************************************/
143 static PyMethodDef BPy_Camera_methods[] = {
144         /* name, method, flags, doc */
145         {"getIpo", ( PyCFunction ) Camera_getIpo, METH_NOARGS,
146          "() - Return Camera Data Ipo"},
147         {"getName", ( PyCFunction ) GenericLib_getName, METH_NOARGS,
148          "() - Return Camera Data name"},
149         {"getType", ( PyCFunction ) Camera_oldgetType, METH_NOARGS,
150          "() - Return Camera type - 'persp':0, 'ortho':1"},
151         {"getMode", ( PyCFunction ) Camera_oldgetMode, METH_NOARGS,
152          "() - Return Camera mode flags (or'ed value) -\n"
153          "     'showLimits':1, 'showMist':2"},
154         {"getLens", ( PyCFunction ) Camera_oldgetLens, METH_NOARGS,
155          "() - Return *perspective* Camera lens value"},
156         {"getScale", ( PyCFunction ) Camera_oldgetScale, METH_NOARGS,
157          "() - Return *ortho* Camera scale value"},
158         {"getClipStart", ( PyCFunction ) Camera_oldgetClipStart, METH_NOARGS,
159          "() - Return Camera clip start value"},
160         {"getClipEnd", ( PyCFunction ) Camera_oldgetClipEnd, METH_NOARGS,
161          "() - Return Camera clip end value"},
162         {"getDrawSize", ( PyCFunction ) Camera_oldgetDrawSize, METH_NOARGS,
163          "() - Return Camera draw size value"},
164         {"setIpo", ( PyCFunction ) Camera_oldsetIpo, METH_VARARGS,
165          "(Blender Ipo) - Set Camera Ipo"},
166         {"clearIpo", ( PyCFunction ) Camera_oldclearIpo, METH_NOARGS,
167          "() - Unlink Ipo from this Camera."},
168          {"insertIpoKey", ( PyCFunction ) Camera_insertIpoKey, METH_VARARGS,
169          "( Camera IPO type ) - Inserts a key into IPO"},
170         {"setName", ( PyCFunction ) GenericLib_setName_with_method, METH_VARARGS,
171          "(s) - Set Camera Data name"},
172         {"setType", ( PyCFunction ) Camera_oldsetType, METH_O,
173          "(s) - Set Camera type, which can be 'persp' or 'ortho'"},
174         {"setMode", ( PyCFunction ) Camera_oldsetMode, METH_VARARGS,
175          "(<s<,s>>) - Set Camera mode flag(s): 'showLimits' and 'showMist'"},
176         {"setLens", ( PyCFunction ) Camera_oldsetLens, METH_O,
177          "(f) - Set *perpective* Camera lens value"},
178         {"setScale", ( PyCFunction ) Camera_oldsetScale, METH_O,
179          "(f) - Set *ortho* Camera scale value"},
180         {"setClipStart", ( PyCFunction ) Camera_oldsetClipStart, METH_O,
181          "(f) - Set Camera clip start value"},
182         {"setClipEnd", ( PyCFunction ) Camera_oldsetClipEnd, METH_O,
183          "(f) - Set Camera clip end value"},
184         {"setDrawSize", ( PyCFunction ) Camera_oldsetDrawSize, METH_O,
185          "(f) - Set Camera draw size value"},
186         {"getScriptLinks", ( PyCFunction ) Camera_oldgetScriptLinks, METH_O,
187          "(eventname) - Get a list of this camera's scriptlinks (Text names) "
188          "of the given type\n"
189          "(eventname) - string: FrameChanged, Redraw or Render."},
190         {"addScriptLink", ( PyCFunction ) Camera_addScriptLink, METH_VARARGS,
191          "(text, evt) - Add a new camera scriptlink.\n"
192          "(text) - string: an existing Blender Text name;\n"
193          "(evt) string: FrameChanged, Redraw or Render."},
194         {"clearScriptLinks", ( PyCFunction ) Camera_clearScriptLinks,
195          METH_NOARGS,
196          "() - Delete all scriptlinks from this camera.\n"
197          "([s1<,s2,s3...>]) - Delete specified scriptlinks from this camera."},
198         {"__copy__", ( PyCFunction ) Camera_copy, METH_NOARGS,
199          "() - Return a copy of the camera."},
200         {"copy", ( PyCFunction ) Camera_copy, METH_NOARGS,
201          "() - Return a copy of the camera."},
202         {NULL, NULL, 0, NULL}
203 };
204
205 /*****************************************************************************/
206 /* Python Camera_Type callback function prototypes:                          */
207 /*****************************************************************************/
208 static int Camera_compare( BPy_Camera * a, BPy_Camera * b );
209 static PyObject *Camera_repr( BPy_Camera * self );
210
211 static PyObject *M_Camera_New( PyObject * self, PyObject * args,
212                                PyObject * kwords )
213 {
214         char *type_str = "persp";       /* "persp" is type 0, "ortho" is type 1 */
215         char *name_str = "Camera";
216         static char *kwlist[] = { "type_str", "name_str", NULL };
217         PyObject *pycam;        /* for Camera Data object wrapper in Python */
218         Camera *blcam;          /* for actual Camera Data we create in Blender */
219
220         /* Parse the arguments passed in by the Python interpreter */
221         if( !PyArg_ParseTupleAndKeywords( args, kwords, "|ss", kwlist,
222                                           &type_str, &name_str ) )
223                 /* We expected string(s) (or nothing) as argument, but we didn't get that. */
224                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
225                                               "expected zero, one or two strings as arguments" );
226
227         blcam = add_camera( name_str ); /* first create the Camera Data in Blender */
228
229         if( blcam )             /* now create the wrapper obj in Python */
230                 pycam = Camera_CreatePyObject( blcam );
231         else
232                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
233                                               "couldn't create Camera Data in Blender" );
234
235         /* let's return user count to zero, because ... */
236         blcam->id.us = 0;       /* ... add_camera() incref'ed it */
237         /* XXX XXX Do this in other modules, too */
238
239         if( pycam == NULL )
240                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
241                                               "couldn't create Camera PyObject" );
242
243         if( strcmp( type_str, "persp" ) == 0 )
244                 /* default, no need to set, so */
245                 /*blcam->type = (short)EXPP_CAM_TYPE_PERSP */
246                 ;
247         /* we comment this line */
248         else if( strcmp( type_str, "ortho" ) == 0 )
249                 blcam->type = ( short ) EXPP_CAM_TYPE_ORTHO;
250         else
251                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
252                                               "unknown camera type" );
253         
254         return pycam;
255 }
256
257 static PyObject *M_Camera_Get( PyObject * self, PyObject * args )
258 {
259         char *name = NULL;
260         Camera *cam_iter;
261
262         if( !PyArg_ParseTuple( args, "|s", &name ) )
263                 return EXPP_ReturnPyObjError( PyExc_TypeError,
264                                               "expected string argument (or nothing)" );
265
266         cam_iter = G.main->camera.first;
267
268         if( name ) {            /* (name) - Search camera by name */
269
270                 PyObject *wanted_cam = NULL;
271
272                 while( cam_iter && !wanted_cam ) {
273
274                         if( strcmp( name, cam_iter->id.name + 2 ) == 0 ) {
275                                 wanted_cam = Camera_CreatePyObject( cam_iter );
276                                 break;
277                         }
278
279                         cam_iter = cam_iter->id.next;
280                 }
281
282                 if( !wanted_cam ) {     /* Requested camera doesn't exist */
283                         char error_msg[64];
284                         PyOS_snprintf( error_msg, sizeof( error_msg ),
285                                        "Camera \"%s\" not found", name );
286                         return EXPP_ReturnPyObjError( PyExc_NameError,
287                                                       error_msg );
288                 }
289
290                 return wanted_cam;
291         }
292
293         else {                  /* () - return a list of wrappers for all cameras in the scene */
294                 int index = 0;
295                 PyObject *cam_pylist, *pyobj;
296
297                 cam_pylist =
298                         PyList_New( BLI_countlist( &( G.main->camera ) ) );
299
300                 if( !cam_pylist )
301                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
302                                                       "couldn't create PyList" );
303
304                 while( cam_iter ) {
305                         pyobj = Camera_CreatePyObject( cam_iter );
306
307                         if( !pyobj ) {
308                                 Py_DECREF(cam_pylist);
309                                 return EXPP_ReturnPyObjError
310                                         ( PyExc_MemoryError,
311                                           "couldn't create Camera PyObject" );
312                         }
313                         PyList_SET_ITEM( cam_pylist, index, pyobj );
314
315                         cam_iter = cam_iter->id.next;
316                         index++;
317                 }
318
319                 return cam_pylist;
320         }
321 }
322
323 PyObject *Camera_Init( void )
324 {
325         PyObject *submodule;
326
327         if( PyType_Ready( &Camera_Type ) < 0 )
328                 return NULL;
329         
330         submodule = Py_InitModule3( "Blender.Camera",
331                                     M_Camera_methods, M_Camera_doc );
332
333         PyModule_AddIntConstant( submodule, "LENS",     IPOKEY_LENS );
334         PyModule_AddIntConstant( submodule, "CLIPPING", IPOKEY_CLIPPING );
335
336         return submodule;
337 }
338
339 /* Three Python Camera_Type helper functions needed by the Object module: */
340
341 PyObject *Camera_CreatePyObject( Camera * cam )
342 {
343         BPy_Camera *pycam;
344
345         pycam = ( BPy_Camera * ) PyObject_NEW( BPy_Camera, &Camera_Type );
346
347         if( !pycam )
348                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
349                                               "couldn't create BPy_Camera PyObject" );
350
351         pycam->camera = cam;
352         return ( PyObject * ) pycam;
353 }
354
355 Camera *Camera_FromPyObject( PyObject * pyobj )
356 {
357         return ( ( BPy_Camera * ) pyobj )->camera;
358 }
359
360 /*****************************************************************************/
361 /* Python BPy_Camera methods:                                               */
362 /*****************************************************************************/
363
364 static PyObject *Camera_oldgetType( BPy_Camera * self )
365 {
366         return PyInt_FromLong( self->camera->type );
367 }
368
369 static PyObject *Camera_oldgetMode( BPy_Camera * self )
370 {
371         return PyInt_FromLong( self->camera->flag );
372 }
373
374 static PyObject *Camera_oldgetLens( BPy_Camera * self )
375 {
376         return PyFloat_FromDouble( self->camera->lens );
377 }
378
379 static PyObject *Camera_oldgetScale( BPy_Camera * self )
380 {
381         return PyFloat_FromDouble( self->camera->ortho_scale );
382 }
383
384 static PyObject *Camera_oldgetClipStart( BPy_Camera * self )
385 {
386         return PyFloat_FromDouble( self->camera->clipsta );
387 }
388
389 static PyObject *Camera_oldgetClipEnd( BPy_Camera * self )
390 {
391         return PyFloat_FromDouble( self->camera->clipend );
392 }
393
394 static PyObject *Camera_oldgetDrawSize( BPy_Camera * self )
395 {
396         return PyFloat_FromDouble( self->camera->drawsize );
397 }
398
399
400
401 static PyObject *Camera_oldsetIpo( BPy_Camera * self, PyObject * args )
402 {
403         return EXPP_setterWrapper( (void *)self, args, (setter)Camera_setIpo );
404 }
405
406 static PyObject *Camera_oldclearIpo( BPy_Camera * self )
407 {
408         Camera *cam = self->camera;
409         Ipo *ipo = ( Ipo * ) cam->ipo;
410
411         if( ipo ) {
412                 ID *id = &ipo->id;
413                 if( id->us > 0 )
414                         id->us--;
415                 cam->ipo = NULL;
416
417                 return EXPP_incr_ret_True();
418         }
419
420         return EXPP_incr_ret_False(); /* no ipo found */
421 }
422
423 static PyObject *Camera_oldsetType( BPy_Camera * self, PyObject * value )
424 {
425         char *type = PyString_AsString(value);
426
427         if(!value)
428                 return EXPP_ReturnPyObjError( PyExc_TypeError,
429                                               "expected string argument" );
430
431         if( strcmp( type, "persp" ) == 0 )
432                 self->camera->type = ( short ) EXPP_CAM_TYPE_PERSP;
433         else if( strcmp( type, "ortho" ) == 0 )
434                 self->camera->type = ( short ) EXPP_CAM_TYPE_ORTHO;
435         else
436                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
437                                               "unknown camera type" );
438
439         Py_RETURN_NONE;
440 }
441
442 static PyObject *Camera_oldsetMode( BPy_Camera * self, PyObject * args )
443 {
444         char *mode_str1 = NULL, *mode_str2 = NULL;
445         short flag = 0;
446
447         if( !PyArg_ParseTuple( args, "|ss", &mode_str1, &mode_str2 ) )
448                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
449                                               "expected one or two strings as arguments" );
450
451         if( mode_str1 != NULL ) {
452                 if( strcmp( mode_str1, "showLimits" ) == 0 )
453                         flag |= ( short ) EXPP_CAM_MODE_SHOWLIMITS;
454                 else if( strcmp( mode_str1, "showMist" ) == 0 )
455                         flag |= ( short ) EXPP_CAM_MODE_SHOWMIST;
456                 else
457                         return EXPP_ReturnPyObjError( PyExc_AttributeError,
458                                                       "first argument is an unknown camera flag" );
459
460                 if( mode_str2 != NULL ) {
461                         if( strcmp( mode_str2, "showLimits" ) == 0 )
462                                 flag |= ( short ) EXPP_CAM_MODE_SHOWLIMITS;
463                         else if( strcmp( mode_str2, "showMist" ) == 0 )
464                                 flag |= ( short ) EXPP_CAM_MODE_SHOWMIST;
465                         else
466                                 return EXPP_ReturnPyObjError
467                                         ( PyExc_AttributeError,
468                                           "second argument is an unknown camera flag" );
469                 }
470         }
471
472         self->camera->flag = flag;
473
474         Py_RETURN_NONE;
475 }
476
477 static PyObject *Camera_oldsetLens( BPy_Camera * self, PyObject * value )
478 {
479         float param = PyFloat_AsDouble(value);
480
481         if (PyErr_Occurred())
482                 return EXPP_ReturnPyObjError( PyExc_TypeError,
483                                               "expected float argument" );
484
485         self->camera->lens = EXPP_ClampFloat( param,
486                                               EXPP_CAM_LENS_MIN,
487                                               EXPP_CAM_LENS_MAX );
488
489         Py_RETURN_NONE;
490 }
491
492 static PyObject *Camera_oldsetScale( BPy_Camera * self, PyObject * value )
493 {
494         float param = PyFloat_AsDouble(value);
495
496         if (PyErr_Occurred())
497                 return EXPP_ReturnPyObjError( PyExc_TypeError,
498                                               "expected float argument" );
499
500         self->camera->ortho_scale = EXPP_ClampFloat( param,
501                                               EXPP_CAM_SCALE_MIN,
502                                               EXPP_CAM_SCALE_MAX );
503
504         Py_RETURN_NONE;
505 }
506
507 static PyObject *Camera_oldsetClipStart( BPy_Camera * self, PyObject * value )
508 {
509         float param = PyFloat_AsDouble(value);
510
511         if (PyErr_Occurred())
512                 return EXPP_ReturnPyObjError( PyExc_TypeError,
513                                               "expected float argument" );
514
515         self->camera->clipsta = EXPP_ClampFloat( param,
516                                                  EXPP_CAM_CLIPSTART_MIN,
517                                                  EXPP_CAM_CLIPSTART_MAX );
518
519         Py_RETURN_NONE;
520 }
521
522 static PyObject *Camera_oldsetClipEnd( BPy_Camera * self, PyObject * value )
523 {
524         float param = PyFloat_AsDouble(value);
525
526         if (PyErr_Occurred())
527                 return EXPP_ReturnPyObjError( PyExc_TypeError,
528                                               "expected float argument" );
529
530         self->camera->clipend = EXPP_ClampFloat( param,
531                                                  EXPP_CAM_CLIPEND_MIN,
532                                                  EXPP_CAM_CLIPEND_MAX );
533
534         Py_RETURN_NONE;
535 }
536
537 static PyObject *Camera_oldsetDrawSize( BPy_Camera * self, PyObject * value )
538 {
539         float param = PyFloat_AsDouble(value);
540
541         if (PyErr_Occurred())
542                 return EXPP_ReturnPyObjError( PyExc_TypeError,
543                                               "expected float argument" );
544
545         self->camera->drawsize = EXPP_ClampFloat( param,
546                                                   EXPP_CAM_DRAWSIZE_MIN,
547                                                   EXPP_CAM_DRAWSIZE_MAX );
548
549         Py_RETURN_NONE;
550 }
551
552 /* cam.addScriptLink */
553 static PyObject *Camera_addScriptLink( BPy_Camera * self, PyObject * args )
554 {
555         Camera *cam = self->camera;
556         ScriptLink *slink = NULL;
557
558         slink = &( cam )->scriptlink;
559
560         return EXPP_addScriptLink( slink, args, 0 );
561 }
562
563 /* cam.clearScriptLinks */
564 static PyObject *Camera_clearScriptLinks( BPy_Camera * self, PyObject * args )
565 {
566         Camera *cam = self->camera;
567         ScriptLink *slink = NULL;
568
569         slink = &( cam )->scriptlink;
570
571         return EXPP_clearScriptLinks( slink, args );
572 }
573
574 /* cam.getScriptLinks */
575 static PyObject *Camera_oldgetScriptLinks( BPy_Camera * self, PyObject * value )
576 {
577         Camera *cam = self->camera;
578         ScriptLink *slink = NULL;
579         PyObject *ret = NULL;
580
581         slink = &( cam )->scriptlink;
582
583         ret = EXPP_getScriptLinks( slink, value, 0 );
584
585         if( ret )
586                 return ret;
587         else
588                 return NULL;
589 }
590
591 /* cam.__copy__ */
592 static PyObject *Camera_copy( BPy_Camera * self )
593 {
594         PyObject *pycam;        /* for Camera Data object wrapper in Python */
595         Camera *blcam;          /* for actual Camera Data we create in Blender */
596
597         blcam = copy_camera( self->camera );    /* first create the Camera Data in Blender */
598
599         if( blcam )             /* now create the wrapper obj in Python */
600                 pycam = Camera_CreatePyObject( blcam );
601         else
602                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
603                                               "couldn't create Camera Data in Blender" );
604
605         /* let's return user count to zero, because ... */
606         blcam->id.us = 0;       /* ... copy_camera() incref'ed it */
607         /* XXX XXX Do this in other modules, too */
608
609         if( pycam == NULL )
610                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
611                                               "couldn't create Camera PyObject" );
612
613         return pycam;
614 }
615
616 static PyObject *Camera_getType( BPy_Camera * self )
617 {
618         if (self->camera->type == EXPP_CAM_TYPE_PERSP)
619                 return PyString_FromString("persp");
620         else /* must be EXPP_CAM_TYPE_ORTHO */
621                 return PyString_FromString("ortho");
622 }
623
624 static int Camera_setType( BPy_Camera * self, PyObject * value )
625 {
626         char *type = NULL;
627         type = PyString_AsString(value);
628         
629         if (!type)
630                 return EXPP_ReturnIntError( PyExc_ValueError,
631                                               "expected a string" );
632         if (strcmp("persp", type)==0) {
633                 self->camera->type = EXPP_CAM_TYPE_PERSP;
634                 return 0;
635         } else if (strcmp("ortho", type)==0) {
636                 self->camera->type = EXPP_CAM_TYPE_ORTHO;
637                 return 0;
638         }
639         
640         return EXPP_ReturnIntError( PyExc_ValueError,
641                 "expected a string \"ortho\" or \"persp\"" );
642 }
643
644
645
646 static PyObject *Camera_getMode( BPy_Camera * self )
647 {
648         return PyInt_FromLong(self->camera->flag);
649 }
650
651 static int Camera_setMode( BPy_Camera * self, PyObject * value )
652 {
653         unsigned int flag = 0;
654         
655         if( !PyInt_Check( value ) )
656                 return EXPP_ReturnIntError( PyExc_TypeError,
657                         "expected an integer (bitmask) as argument" );
658         
659         flag = ( unsigned int )PyInt_AS_LONG( value );
660         
661         self->camera->flag = flag;
662         return 0;
663 }
664
665 static PyObject *Camera_getIpo( BPy_Camera * self )
666 {
667         struct Ipo *ipo = self->camera->ipo;
668
669         if( ipo )
670                 return Ipo_CreatePyObject( ipo );
671         Py_RETURN_NONE;
672 }
673
674 static int Camera_setIpo( BPy_Camera * self, PyObject * value )
675 {
676         return GenericLib_assignData(value, (void **) &self->camera->ipo, 0, 1, ID_IP, ID_CA);
677 }
678
679 /*
680  * get floating point attributes
681  */
682
683 static PyObject *getFloatAttr( BPy_Camera *self, void *type )
684 {
685         float param;
686         struct Camera *cam= self->camera;
687
688         switch( GET_INT_FROM_POINTER(type) ) {
689         case EXPP_CAM_ATTR_LENS: 
690                 param = cam->lens;
691                 break;
692         case EXPP_CAM_ATTR_ANGLE: 
693                 param = 360.0f * atan(16.0f/cam->lens) / M_PI;
694                 break;
695         case EXPP_CAM_ATTR_DOFDIST: 
696                 param = cam->YF_dofdist;
697                 break;
698         case EXPP_CAM_ATTR_CLIPSTART: 
699                 param = cam->clipsta;
700                 break;
701         case EXPP_CAM_ATTR_CLIPEND: 
702                 param = cam->clipend;
703                 break;
704         case EXPP_CAM_ATTR_DRAWSIZE: 
705                 param = cam->drawsize;
706                 break;
707         case EXPP_CAM_ATTR_SCALE: 
708                 param = cam->ortho_scale;
709                 break;
710         case EXPP_CAM_ATTR_ALPHA: 
711                 param = cam->passepartalpha;
712                 break;
713         case EXPP_CAM_ATTR_SHIFTX: 
714                 param = cam->shiftx;
715                 break;
716         case EXPP_CAM_ATTR_SHIFTY:
717                 param = cam->shifty;
718                 break;
719         
720         default:
721                 return EXPP_ReturnPyObjError( PyExc_RuntimeError, 
722                                 "undefined type in getFloatAttr" );
723         }
724
725         return PyFloat_FromDouble( param );
726 }
727
728
729
730 /*
731  * set floating point attributes which require clamping
732  */
733
734 static int setFloatAttrClamp( BPy_Camera *self, PyObject *value, void *type )
735 {
736         float *param;
737         struct Camera *cam = self->camera;
738         float min, max;
739         int ret;
740  
741         switch( GET_INT_FROM_POINTER(type) ) {
742         case EXPP_CAM_ATTR_LENS:
743                 min = 1.0;
744                 max = 250.0;
745                 param = &cam->lens;
746                 break;
747         case EXPP_CAM_ATTR_ANGLE:
748                 min = 7.323871;
749                 max = 172.847331;
750                 param = &cam->lens;
751                 break;
752         case EXPP_CAM_ATTR_DOFDIST:
753                 min = 0.0;
754                 max = 5000.0;
755                 param = &cam->YF_dofdist;
756                 break;
757         case EXPP_CAM_ATTR_CLIPSTART:
758                 min = 0.0;
759                 max = 100.0;
760                 param = &cam->clipsta;
761                 break;
762         case EXPP_CAM_ATTR_CLIPEND:
763                 min = 1.0;
764                 max = 5000.0;
765                 param = &cam->clipend;
766                 break;
767         case EXPP_CAM_ATTR_DRAWSIZE:
768                 min = 0.1f;
769                 max = 10.0;
770                 param = &cam->drawsize;
771                 break;
772         case EXPP_CAM_ATTR_SCALE:
773                 min = 0.01f;
774                 max = 1000.0;
775                 param = &cam->ortho_scale;
776                 break;
777         case EXPP_CAM_ATTR_ALPHA:
778                 min = 0.0;
779                 max = 1.0;
780                 param = &cam->passepartalpha;
781                 break;
782         case EXPP_CAM_ATTR_SHIFTX:
783                 min = -2.0;
784                 max =  2.0;
785                 param = &cam->shiftx;
786                 break;
787         case EXPP_CAM_ATTR_SHIFTY:
788                 min = -2.0;
789                 max =  2.0;
790                 param = &cam->shifty;
791                 break;
792         
793         default:
794                 return EXPP_ReturnIntError( PyExc_RuntimeError,
795                                 "undefined type in setFloatAttrClamp" );
796         }
797
798         ret = EXPP_setFloatClamped( value, param, min, max );
799         
800         if (ret==0) {
801                 if (GET_INT_FROM_POINTER(type) == EXPP_CAM_ATTR_ANGLE) {
802                         cam->lens = 16.0f / tan(M_PI*cam->lens/360.0f);
803                 }
804         }
805         return ret;
806 }
807
808
809 /*
810  * get floating point attributes
811  */
812
813 static PyObject *getFlagAttr( BPy_Camera *self, void *type )
814 {
815         if (self->camera->flag & GET_INT_FROM_POINTER(type))
816                 Py_RETURN_TRUE;
817         else
818                 Py_RETURN_FALSE;
819 }
820
821 /*
822  * set floating point attributes which require clamping
823  */
824
825 static int setFlagAttr( BPy_Camera *self, PyObject *value, void *type )
826 {
827         int param = PyObject_IsTrue( value );
828         if( param == -1 )
829                 return EXPP_ReturnIntError( PyExc_TypeError,
830                                 "expected True/False or 0/1" );
831         
832         if (param)
833                 self->camera->flag |= GET_INT_FROM_POINTER(type);
834         else
835                 self->camera->flag &= ~GET_INT_FROM_POINTER(type);
836         return 0;
837 }
838
839
840 /*****************************************************************************/
841 /* Python attributes get/set structure:                                      */
842 /*****************************************************************************/
843 static PyGetSetDef BPy_Camera_getseters[] = {
844         GENERIC_LIB_GETSETATTR,
845         {"type",
846          (getter)Camera_getType, (setter)Camera_setType,
847          "camera type \"persp\" or \"ortho\"",
848          NULL},
849         {"mode",
850          (getter)Camera_getMode, (setter)Camera_setMode,
851          "Cameras mode",
852          NULL},
853         {"ipo",
854          (getter)Camera_getIpo, (setter)Camera_setIpo,
855          "Cameras ipo",
856          NULL},
857         
858         /* float settings */
859         {"lens",
860          (getter)getFloatAttr, (setter)setFloatAttrClamp,
861          "lens angle for perspective cameras",
862          (void *)EXPP_CAM_ATTR_LENS},
863         {"angle",
864          (getter)getFloatAttr, (setter)setFloatAttrClamp,
865          "lens angle for perspective cameras",
866          (void *)EXPP_CAM_ATTR_ANGLE},
867          
868         {"scale",
869          (getter)getFloatAttr, (setter)setFloatAttrClamp,
870          "scale for ortho cameras",
871          (void *)EXPP_CAM_ATTR_SCALE},
872         {"clipStart",
873          (getter)getFloatAttr, (setter)setFloatAttrClamp,
874          "the cameras clip start",
875          (void *)EXPP_CAM_ATTR_CLIPSTART},
876         {"clipEnd",
877          (getter)getFloatAttr, (setter)setFloatAttrClamp,
878          "the cameras clip end",
879          (void *)EXPP_CAM_ATTR_CLIPEND},
880         {"shiftX",
881          (getter)getFloatAttr, (setter)setFloatAttrClamp,
882          "the cameras X perspective shift",
883          (void *)EXPP_CAM_ATTR_SHIFTX},
884         {"shiftY",
885          (getter)getFloatAttr, (setter)setFloatAttrClamp,
886          "the cameras Y perspective shift",
887          (void *)EXPP_CAM_ATTR_SHIFTY},
888         {"dofDist",
889          (getter)getFloatAttr, (setter)setFloatAttrClamp,
890          "cameras dof distance",
891          (void *)EXPP_CAM_ATTR_DOFDIST},
892         {"drawSize",
893          (getter)getFloatAttr, (setter)setFloatAttrClamp,
894          "the cameras display size",
895          (void *)EXPP_CAM_ATTR_DRAWSIZE},
896         {"alpha",
897          (getter)getFloatAttr, (setter)setFloatAttrClamp,
898          "passepart alpha value for display",
899          (void *)EXPP_CAM_ATTR_ALPHA},
900          
901         /* flags - use flags as defined in DNA_camera_types.h */
902         {"drawLimits",
903          (getter)getFlagAttr, (setter)setFlagAttr,
904          "toggle the draw limits display flag",
905          (void *)CAM_SHOWLIMITS},
906         {"drawMist",
907          (getter)getFlagAttr, (setter)setFlagAttr,
908          "toggle the draw mist display flag",
909          (void *)CAM_SHOWMIST},
910         {"drawName",
911          (getter)getFlagAttr, (setter)setFlagAttr,
912          "toggle the draw name display flag",
913          (void *)CAM_SHOWNAME},
914         {"drawTileSafe",
915          (getter)getFlagAttr, (setter)setFlagAttr,
916          "toggle the tile safe display flag",
917          (void *)CAM_SHOWTITLESAFE},
918         {"drawPassepartout",
919          (getter)getFlagAttr, (setter)setFlagAttr,
920          "toggle the passPartOut display flag",
921          (void *)CAM_SHOWPASSEPARTOUT},
922         {"angleToggle",
923          (getter)getFlagAttr, (setter)setFlagAttr,
924          "toggle the camera input unit flag",
925          (void *)CAM_ANGLETOGGLE},
926         {NULL,NULL,NULL,NULL}  /* Sentinel */
927 };
928
929
930 /*****************************************************************************/
931 /* Python Camera_Type structure definition:                               */
932 /*****************************************************************************/
933 PyTypeObject Camera_Type = {
934         PyObject_HEAD_INIT( NULL )  /* required py macro */
935         0,                          /* ob_size */
936         /*  For printing, in format "<module>.<name>" */
937         "Blender Camera",           /* char *tp_name; */
938         sizeof( BPy_Camera ),       /* int tp_basicsize; */
939         0,                          /* tp_itemsize;  For allocation */
940
941         /* Methods to implement standard operations */
942
943         NULL,                                           /* destructor tp_dealloc; */
944         NULL,                       /* printfunc tp_print; */
945         NULL,                       /* getattrfunc tp_getattr; */
946         NULL,                       /* setattrfunc tp_setattr; */
947         ( cmpfunc ) Camera_compare, /* cmpfunc tp_compare; */
948         ( reprfunc ) Camera_repr,   /* reprfunc tp_repr; */
949
950         /* Method suites for standard classes */
951
952         NULL,                       /* PyNumberMethods *tp_as_number; */
953         NULL,                       /* PySequenceMethods *tp_as_sequence; */
954         NULL,                       /* PyMappingMethods *tp_as_mapping; */
955
956         /* More standard operations (here for binary compatibility) */
957
958         NULL,                       /* hashfunc tp_hash; */
959         NULL,                       /* ternaryfunc tp_call; */
960         NULL,                       /* reprfunc tp_str; */
961         NULL,                       /* getattrofunc tp_getattro; */
962         NULL,                       /* setattrofunc tp_setattro; */
963
964         /* Functions to access object as input/output buffer */
965         NULL,                       /* PyBufferProcs *tp_as_buffer; */
966
967   /*** Flags to define presence of optional/expanded features ***/
968         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
969
970         NULL,                       /*  char *tp_doc;  Documentation string */
971   /*** Assigned meaning in release 2.0 ***/
972         /* call function for all accessible objects */
973         NULL,                       /* traverseproc tp_traverse; */
974
975         /* delete references to contained objects */
976         NULL,                       /* inquiry tp_clear; */
977
978   /***  Assigned meaning in release 2.1 ***/
979   /*** rich comparisons ***/
980         NULL,                       /* richcmpfunc tp_richcompare; */
981
982   /***  weak reference enabler ***/
983         0,                          /* long tp_weaklistoffset; */
984
985   /*** Added in release 2.2 ***/
986         /*   Iterators */
987         NULL, /* getiterfunc tp_iter; */
988         NULL, /* iternextfunc tp_iternext; */
989
990   /*** Attribute descriptor and subclassing stuff ***/
991         BPy_Camera_methods,       /* struct PyMethodDef *tp_methods; */
992         NULL,                       /* struct PyMemberDef *tp_members; */
993         BPy_Camera_getseters,                       /* struct PyGetSetDef *tp_getset; */
994         NULL,                       /* struct _typeobject *tp_base; */
995         NULL,                       /* PyObject *tp_dict; */
996         NULL,                       /* descrgetfunc tp_descr_get; */
997         NULL,                       /* descrsetfunc tp_descr_set; */
998         0,                          /* long tp_dictoffset; */
999         NULL,                       /* initproc tp_init; */
1000         NULL,                       /* allocfunc tp_alloc; */
1001         NULL,                       /* newfunc tp_new; */
1002         /*  Low-level free-memory routine */
1003         NULL,                       /* freefunc tp_free;  */
1004         /* For PyObject_IS_GC */
1005         NULL,                       /* inquiry tp_is_gc;  */
1006         NULL,                       /* PyObject *tp_bases; */
1007         /* method resolution order */
1008         NULL,                       /* PyObject *tp_mro;  */
1009         NULL,                       /* PyObject *tp_cache; */
1010         NULL,                       /* PyObject *tp_subclasses; */
1011         NULL,                       /* PyObject *tp_weaklist; */
1012         NULL
1013 };
1014
1015
1016
1017 static int Camera_compare( BPy_Camera * a, BPy_Camera * b )
1018 {
1019         Camera *pa = a->camera, *pb = b->camera;
1020         return ( pa == pb ) ? 0 : -1;
1021 }
1022
1023 static PyObject *Camera_repr( BPy_Camera * self )
1024 {
1025         return PyString_FromFormat( "[Camera \"%s\"]",
1026                                     self->camera->id.name + 2 );
1027 }
1028
1029 /*
1030  * Camera_insertIpoKey()
1031  *  inserts Camera IPO key for LENS and CLIPPING
1032  */
1033
1034 static PyObject *Camera_insertIpoKey( BPy_Camera * self, PyObject * args )
1035 {
1036         int key = 0, flag = 0;
1037
1038         if( !PyArg_ParseTuple( args, "i", &( key ) ) )
1039                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1040                                                                                 "expected int argument" ) );
1041         
1042         /* flag should be initialised with the 'autokeying' flags like for normal keying */
1043         if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
1044         
1045         if (key == IPOKEY_LENS){
1046                 insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_LENS, flag);     
1047         }
1048         else if (key == IPOKEY_CLIPPING){
1049                 insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_STA, flag);
1050                 insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_END, flag);   
1051         }
1052
1053         allspace(REMAKEIPO, 0);
1054         EXPP_allqueue(REDRAWIPO, 0);
1055         EXPP_allqueue(REDRAWVIEW3D, 0);
1056         EXPP_allqueue(REDRAWACTION, 0);
1057         EXPP_allqueue(REDRAWNLA, 0);
1058
1059         Py_RETURN_NONE;
1060 }