81646cae727f6f961db668a5dc32094c993aa809
[blender-staging.git] / source / blender / python / api2_2x / Camera.c
1 /* 
2  *
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): Willian P. Germano
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30 */
31
32 #include "Camera.h"
33
34 /*****************************************************************************/
35 /* Function:              M_Camera_New                                       */
36 /* Python equivalent:     Blender.Camera.New                                 */
37 /*****************************************************************************/
38 static PyObject *M_Camera_New(PyObject *self, PyObject *args, PyObject *keywords)
39 {
40   char        *type_str = "persp"; /* "persp" is type 0, "ortho" is type 1 */
41   char        *name_str = "CamData";
42   static char *kwlist[] = {"type_str", "name_str", NULL};
43   C_Camera    *pycam; /* for Camera Data object wrapper in Python */
44   Camera      *blcam; /* for actual Camera Data we create in Blender */
45   char        buf[21];
46
47   printf ("In Camera_New()\n");
48
49   if (!PyArg_ParseTupleAndKeywords(args, keywords, "|ss", kwlist,
50                                    &type_str, &name_str))
51   /* We expected string(s) (or nothing) as argument, but we didn't get that. */
52     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
53             "expected zero, one or two strings as arguments"));
54
55   blcam = add_camera(); /* first create the Camera Data in Blender */
56
57   if (blcam) /* now create the wrapper obj in Python */
58     pycam = (C_Camera *)PyObject_NEW(C_Camera, &Camera_Type);
59   else
60     return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
61                             "couldn't create Camera Data in Blender"));
62
63   if (pycam == NULL)
64     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
65                             "couldn't create Camera Data object"));
66
67   pycam->camera = blcam; /* link Python camera wrapper to Blender Camera */
68
69   if (strcmp (type_str, "persp") == 0) /* default, no need to set, so */
70     /*blcam->type = (short)EXPP_CAM_TYPE_PERSP*/; /* we comment this line */
71   else if (strcmp (type_str, "ortho") == 0)
72     blcam->type = (short)EXPP_CAM_TYPE_ORTHO;
73   else
74     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
75             "unknown camera type"));
76
77   if (strcmp(name_str, "CamData") == 0)
78     return (PyObject *)pycam;
79   else { /* user gave us a name for the camera, use it */
80     PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
81     rename_id(&blcam->id, buf); /* proper way in Blender */
82   }
83
84   return (PyObject *)pycam;
85 }
86
87 /*****************************************************************************/
88 /* Function:              M_Camera_Get                                       */
89 /* Python equivalent:     Blender.Camera.Get                                 */
90 /*****************************************************************************/
91 static PyObject *M_Camera_Get(PyObject *self, PyObject *args)
92 {
93   char     *name;
94   Camera   *cam_iter;
95   C_Camera *wanted_cam;
96
97   printf ("In Camera_Get()\n");
98   if (!PyArg_ParseTuple(args, "s", &name))
99     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
100             "expected string argument"));
101
102   /* Use the name to search for the camera requested */
103   wanted_cam = NULL;
104   cam_iter = G.main->camera.first;
105
106   while ((cam_iter) && (wanted_cam == NULL)) {
107
108     if (strcmp (name, cam_iter->id.name+2) == 0) {
109       wanted_cam = (C_Camera *)PyObject_NEW(C_Camera, &Camera_Type);
110       if (wanted_cam) wanted_cam->camera = cam_iter;
111     }
112
113     cam_iter = cam_iter->id.next;
114   }
115
116   if (wanted_cam == NULL) { /* Requested camera doesn't exist */
117     char error_msg[64];
118     PyOS_snprintf(error_msg, sizeof(error_msg),
119                     "Camera \"%s\" not found", name);
120     return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg));
121   }
122
123   return (PyObject*)wanted_cam;
124 }
125
126 /*****************************************************************************/
127 /* Function:              M_Camera_Init                                      */
128 /*****************************************************************************/
129 PyObject *M_Camera_Init (void)
130 {
131   PyObject  *submodule;
132
133   printf ("In M_Camera_Init()\n");
134   submodule = Py_InitModule3("Blender.Camera",
135                   M_Camera_methods, M_Camera_doc);
136
137   return (submodule);
138 }
139
140 /*****************************************************************************/
141 /* Python C_Camera methods:                                                  */
142 /*****************************************************************************/
143 static PyObject *Camera_getName(C_Camera *self)
144 {
145   PyObject *attr = PyString_FromString(self->camera->id.name+2);
146
147   if (attr) return attr;
148
149   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
150                                    "couldn't get Camera.name attribute"));
151 }
152
153 static PyObject *Camera_getType(C_Camera *self)
154 {
155   PyObject *attr = PyInt_FromLong(self->camera->type);
156
157   if (attr) return attr;
158
159   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
160                                    "couldn't get Camera.type attribute"));
161 }
162
163 static PyObject *Camera_getMode(C_Camera *self)
164 {
165   PyObject *attr = PyInt_FromLong(self->camera->flag);
166
167   if (attr) return attr;
168
169   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
170                                    "couldn't get Camera.Mode attribute"));
171 }
172
173 static PyObject *Camera_getLens(C_Camera *self)
174 {
175   PyObject *attr = PyFloat_FromDouble(self->camera->lens);
176
177   if (attr) return attr;
178
179   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
180                                    "couldn't get Camera.lens attribute"));
181 }
182
183 static PyObject *Camera_getClipStart(C_Camera *self)
184 {
185   PyObject *attr = PyFloat_FromDouble(self->camera->clipsta);
186
187   if (attr) return attr;
188
189   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
190                                    "couldn't get Camera.clipStart attribute"));
191 }
192
193 static PyObject *Camera_getClipEnd(C_Camera *self)
194 {
195   PyObject *attr = PyFloat_FromDouble(self->camera->clipend);
196
197   if (attr) return attr;
198
199   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
200                                    "couldn't get Camera.clipEnd attribute"));
201 }
202
203 static PyObject *Camera_getDrawSize(C_Camera *self)
204 {
205   PyObject *attr = PyFloat_FromDouble(self->camera->drawsize);
206
207   if (attr) return attr;
208
209   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
210                                    "couldn't get Camera.drawSize attribute"));
211 }
212
213 static PyObject *Camera_rename(C_Camera *self, PyObject *args)
214 {
215   char *name;
216   char buf[21];
217
218   if (!PyArg_ParseTuple(args, "s", &name))
219     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
220                                      "expected string argument"));
221
222   PyOS_snprintf(buf, sizeof(buf), "%s", name);
223
224   rename_id(&self->camera->id, buf);
225
226   Py_INCREF(Py_None);
227   return Py_None;
228 }
229
230 static PyObject *Camera_setType(C_Camera *self, PyObject *args)
231 {
232   char *type;
233
234   if (!PyArg_ParseTuple(args, "s", &type))
235     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
236                                      "expected string argument"));
237
238   if (strcmp (type, "persp") == 0)
239     self->camera->type = (short)EXPP_CAM_TYPE_PERSP;
240   else if (strcmp (type, "ortho") == 0)
241     self->camera->type = (short)EXPP_CAM_TYPE_ORTHO;  
242   else
243     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
244                                      "unknown camera type"));
245
246   Py_INCREF(Py_None);
247   return Py_None;
248 }
249
250 /* This one is 'private'. It is not really a method, just a helper function for
251  * when script writers use Camera.type = t instead of Camera.setType(t), since in
252  * the first case t should be an int and in the second a string. So while the
253  * method setType expects a string ('persp' or 'ortho') or an empty argument,
254  * this function should receive an int (0 or 1). */
255 static PyObject *Camera_setIntType(C_Camera *self, PyObject *args)
256 {
257   short value;
258
259   if (!PyArg_ParseTuple(args, "h", &value))
260     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
261                                      "expected int argument: 0 or 1"));
262
263   if (value == 0 || value == 1)
264     self->camera->type = value;
265   else
266     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
267                                      "expected int argument: 0 or 1"));
268
269   Py_INCREF(Py_None);
270   return Py_None;
271 }
272
273 static PyObject *Camera_setMode(C_Camera *self, PyObject *args)
274 {
275   char *mode_str1 = NULL, *mode_str2 = NULL;
276   short flag = 0;
277
278   if (!PyArg_ParseTuple(args, "|ss", &mode_str1, &mode_str2))
279     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
280             "expected one or two strings as arguments"));
281   
282   if (mode_str1 != NULL) {
283     if (strcmp(mode_str1, "showLimits") == 0)
284       flag |= (short)EXPP_CAM_MODE_SHOWLIMITS;
285     else if (strcmp(mode_str1, "showMist") == 0)
286       flag |= (short)EXPP_CAM_MODE_SHOWMIST;
287     else
288       return (EXPP_ReturnPyObjError (PyExc_AttributeError,
289                               "first argument is an unknown camera flag"));
290
291     if (mode_str2 != NULL) {
292       if (strcmp(mode_str2, "showLimits") == 0)
293         flag |= (short)EXPP_CAM_MODE_SHOWLIMITS;
294       else if (strcmp(mode_str2, "showMist") == 0)
295         flag |= (short)EXPP_CAM_MODE_SHOWMIST;
296       else
297         return (EXPP_ReturnPyObjError (PyExc_AttributeError,
298                               "second argument is an unknown camera flag"));
299     }
300   }
301
302   self->camera->flag = flag;
303
304   Py_INCREF(Py_None);
305   return Py_None;
306 }
307
308 /* Another helper function, for the same reason.
309  * (See comment before Camera_setIntType above). */
310 static PyObject *Camera_setIntMode(C_Camera *self, PyObject *args)
311 {
312   short value;
313
314   if (!PyArg_ParseTuple(args, "h", &value))
315     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
316                                      "expected int argument in [0,3]"));
317
318   if (value >= 0 && value <= 3)
319     self->camera->flag = value;
320   else
321     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
322                                      "expected int argument in [0,3]"));
323
324   Py_INCREF(Py_None);
325   return Py_None;
326 }
327
328 static PyObject *Camera_setLens(C_Camera *self, PyObject *args)
329 {
330   float value;
331   
332   if (!PyArg_ParseTuple(args, "f", &value))
333     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
334                                      "expected float argument"));
335   
336   self->camera->lens = EXPP_ClampFloat (value,
337                   EXPP_CAM_LENS_MIN, EXPP_CAM_LENS_MAX);
338   
339   Py_INCREF(Py_None);
340   return Py_None;
341 }
342
343 static PyObject *Camera_setClipStart(C_Camera *self, PyObject *args)
344 {
345   float value;
346   
347   if (!PyArg_ParseTuple(args, "f", &value))
348     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
349                                      "expected float argument"));
350
351   self->camera->clipsta = EXPP_ClampFloat (value,
352                   EXPP_CAM_CLIPSTART_MIN, EXPP_CAM_CLIPSTART_MAX);
353   
354   Py_INCREF(Py_None);
355   return Py_None;
356 }
357
358 static PyObject *Camera_setClipEnd(C_Camera *self, PyObject *args)
359 {
360   float value;
361   
362   if (!PyArg_ParseTuple(args, "f", &value))
363     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
364                                      "expected float argument"));
365
366   self->camera->clipend = EXPP_ClampFloat (value,
367                   EXPP_CAM_CLIPEND_MIN, EXPP_CAM_CLIPEND_MAX);
368
369   Py_INCREF(Py_None);
370   return Py_None;
371 }
372
373 static PyObject *Camera_setDrawSize(C_Camera *self, PyObject *args)
374 {
375   float value;
376   
377   if (!PyArg_ParseTuple(args, "f", &value))
378     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
379                                      "expected a float number as argument"));
380
381   self->camera->drawsize = EXPP_ClampFloat (value,
382                   EXPP_CAM_DRAWSIZE_MIN, EXPP_CAM_DRAWSIZE_MAX);
383
384   Py_INCREF(Py_None);
385   return Py_None;
386 }
387
388 /*****************************************************************************/
389 /* Function:    CameraDeAlloc                                                */
390 /* Description: This is a callback function for the C_Camera type. It is     */
391 /*              the destructor function.                                     */
392 /*****************************************************************************/
393 static void CameraDeAlloc (C_Camera *self)
394 {
395   PyObject_DEL (self);
396 }
397
398 /*****************************************************************************/
399 /* Function:    CameraGetAttr                                                */
400 /* Description: This is a callback function for the C_Camera type. It is     */
401 /*              the function that accesses C_Camera "member variables" and   */
402 /*              methods.                                                     */
403 /*****************************************************************************/
404 static PyObject *CameraGetAttr (C_Camera *self, char *name)
405 {
406   PyObject *attr = Py_None;
407
408   if (strcmp(name, "name") == 0)
409     attr = PyString_FromString(self->camera->id.name+2);
410   else if (strcmp(name, "type") == 0)
411     attr = PyInt_FromLong(self->camera->type);
412   else if (strcmp(name, "mode") == 0)
413     attr = PyInt_FromLong(self->camera->flag);
414   else if (strcmp(name, "lens") == 0)
415     attr = PyFloat_FromDouble(self->camera->lens);
416   else if (strcmp(name, "clipStart") == 0)
417     attr = PyFloat_FromDouble(self->camera->clipsta);
418   else if (strcmp(name, "clipEnd") == 0)
419     attr = PyFloat_FromDouble(self->camera->clipend);
420   else if (strcmp(name, "drawSize") == 0)
421     attr = PyFloat_FromDouble(self->camera->drawsize);
422
423   else if (strcmp(name, "Types") == 0) {
424     attr = Py_BuildValue("{s:h,s:h}", "persp", EXPP_CAM_TYPE_PERSP,
425                                       "ortho", EXPP_CAM_TYPE_ORTHO);
426   }
427
428   else if (strcmp(name, "Modes") == 0) {
429     attr = Py_BuildValue("{s:h,s:h}", "showLimits", EXPP_CAM_MODE_SHOWLIMITS,
430                                   "showMist", EXPP_CAM_MODE_SHOWMIST);
431   }
432
433   else if (strcmp(name, "__members__") == 0) {
434     attr = Py_BuildValue("[s,s,s,s,s,s,s,s,s]",
435                     "name", "type", "mode", "lens", "clipStart",
436                     "clipEnd", "drawSize", "Types", "Modes");
437   }
438
439   if (!attr)
440     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
441                       "couldn't create PyObject"));
442
443   if (attr != Py_None) return attr; /* member attribute found, return it */
444
445   /* not an attribute, search the methods table */
446   return Py_FindMethod(C_Camera_methods, (PyObject *)self, name);
447 }
448
449 /*****************************************************************************/
450 /* Function:    CameraSetAttr                                                */
451 /* Description: This is a callback function for the C_Camera type. It is the */
452 /*              function that sets Camera Data attributes (member variables).*/
453 /*****************************************************************************/
454 static int CameraSetAttr (C_Camera *self, char *name, PyObject *value)
455 {
456   PyObject *valtuple; 
457   PyObject *error = NULL;
458
459 /* We're playing a trick on the Python API users here.  Even if they use
460  * Camera.member = val instead of Camera.setMember(val), we end up using the
461  * function anyway, since it already has error checking, clamps to the right
462  * interval and updates the Blender Camera structure when necessary. */
463
464 /* First we put "value" in a tuple, because we want to pass it to functions
465  * that only accept PyTuples. Using "N" doesn't increment value's ref count */
466   valtuple = Py_BuildValue("(N)", value);
467
468   if (!valtuple) /* everything OK with our PyObject? */
469     return EXPP_ReturnIntError(PyExc_MemoryError,
470                          "CameraSetAttr: couldn't create PyTuple");
471
472 /* Now we just compare "name" with all possible C_Camera member variables */
473   if (strcmp (name, "name") == 0)
474     error = Camera_rename (self, valtuple);
475   else if (strcmp (name, "type") == 0)
476     error = Camera_setIntType (self, valtuple); /* special case */
477   else if (strcmp (name, "mode") == 0)
478     error = Camera_setIntMode (self, valtuple); /* special case */
479   else if (strcmp (name, "lens") == 0)
480     error = Camera_setLens (self, valtuple);
481   else if (strcmp (name, "clipStart") == 0)
482     error = Camera_setClipStart (self, valtuple);
483   else if (strcmp (name, "clipEnd") == 0)
484     error = Camera_setClipEnd (self, valtuple);
485   else if (strcmp (name, "drawSize") == 0)
486     error = Camera_setDrawSize (self, valtuple);
487
488   else { /* Error */
489     Py_DECREF(valtuple);
490
491     if ((strcmp (name, "Types") == 0) || /* user tried to change a */
492         (strcmp (name, "Modes") == 0))   /* constant dict type ... */
493       return (EXPP_ReturnIntError (PyExc_AttributeError,
494                    "constant dictionary -- cannot be changed"));
495
496     else /* ... or no member with the given name was found */
497       return (EXPP_ReturnIntError (PyExc_KeyError,
498                    "attribute not found"));
499   }
500
501 /* valtuple won't be returned to the caller, so we need to DECREF it */
502   Py_DECREF(valtuple);
503
504   if (error != Py_None) return -1;
505
506 /* Py_None was incref'ed by the called Camera_set* function. We probably
507  * don't need to decref Py_None (!), but since Python/C API manual tells us
508  * to treat it like any other PyObject regarding ref counting ... */
509   Py_DECREF(Py_None);
510   return 0; /* normal exit */
511 }
512
513 /*****************************************************************************/
514 /* Function:    CameraPrint                                                  */
515 /* Description: This is a callback function for the C_Camera type. It        */
516 /*              builds a meaninful string to 'print' camera objects.         */
517 /*****************************************************************************/
518 static int CameraPrint(C_Camera *self, FILE *fp, int flags)
519
520   fprintf(fp, "[Camera \"%s\"]", self->camera->id.name+2);
521   return 0;
522 }
523
524 /*****************************************************************************/
525 /* Function:    CameraRepr                                                   */
526 /* Description: This is a callback function for the C_Camera type. It        */
527 /*              builds a meaninful string to represent camera objects.       */
528 /*****************************************************************************/
529 static PyObject *CameraRepr (C_Camera *self)
530 {
531   return PyString_FromString(self->camera->id.name+2);
532 }