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