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