* Added 3 missing functions, 2 of them called by blender/src/drawtext.c:
[blender-staging.git] / source / blender / python / api2_2x / Lamp.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 "Lamp.h"
33
34 /*****************************************************************************/
35 /* Function:              M_Lamp_New                                         */
36 /* Python equivalent:     Blender.Lamp.New                                   */
37 /*****************************************************************************/
38 static PyObject *M_Lamp_New(PyObject *self, PyObject *args, PyObject *keywords)
39 {
40   char        *type_str = "Lamp";
41   char        *name_str = "LampData";
42   static char *kwlist[] = {"type_str", "name_str", NULL};
43   C_Lamp      *py_lamp; /* for Lamp Data object wrapper in Python */
44   Lamp        *bl_lamp; /* for actual Lamp Data we create in Blender */
45   char        buf[21];
46
47   printf ("In Lamp_New()\n");
48
49   if (!PyArg_ParseTupleAndKeywords(args, keywords, "|ss", kwlist,
50                           &type_str, &name_str))
51     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
52             "expected string(s) or empty argument"));
53
54   bl_lamp = add_lamp(); /* first create in Blender */
55   if (bl_lamp) /* now create the wrapper obj in Python */
56     py_lamp = (C_Lamp *)PyObject_NEW(C_Lamp, &Lamp_Type);
57   else
58     return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
59                             "couldn't create Lamp Data in Blender"));
60
61   if (py_lamp == NULL)
62     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
63                             "couldn't create Lamp Data object"));
64
65   py_lamp->lamp = bl_lamp; /* link Python lamp wrapper with Blender Lamp */
66
67   if (strcmp (type_str, "Lamp") == 0)
68     bl_lamp->type = (short)EXPP_LAMP_TYPE_LAMP;
69   else if (strcmp (type_str, "Sun") == 0)
70     bl_lamp->type = (short)EXPP_LAMP_TYPE_SUN;
71   else if (strcmp (type_str, "Spot") == 0)
72     bl_lamp->type = (short)EXPP_LAMP_TYPE_SPOT;
73   else if (strcmp (type_str, "Hemi") == 0)
74     bl_lamp->type = (short)EXPP_LAMP_TYPE_HEMI;
75   else
76     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
77             "unknown lamp type"));
78
79   if (strcmp(name_str, "LampData") == 0)
80     return (PyObject *)py_lamp;
81   else { /* user gave us a name for the lamp, use it */
82     PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
83     rename_id(&bl_lamp->id, buf);
84   }
85
86   return (PyObject *)py_lamp;
87 }
88
89 /*****************************************************************************/
90 /* Function:              M_Lamp_Get                                         */
91 /* Python equivalent:     Blender.Lamp.Get                                   */
92 /* Description:           Receives a string and returns the lamp data obj    */
93 /*                        whose name matches the string.  If no argument is  */
94 /*                        passed in, a list of all lamp data names in the    */
95 /*                        current scene is returned.                         */
96 /*****************************************************************************/
97 static PyObject *M_Lamp_Get(PyObject *self, PyObject *args)
98 {
99   char *name = NULL;
100   Lamp *lamp_iter;
101
102         if (!PyArg_ParseTuple(args, "|s", &name))
103     return (EXPP_ReturnPyObjError (PyExc_TypeError,
104             "expected string argument (or nothing)"));
105
106   lamp_iter = G.main->lamp.first;
107
108         if (name) { /* (name) - Search lamp by name */
109
110     C_Lamp *wanted_lamp = NULL;
111
112     while ((lamp_iter) && (wanted_lamp == NULL)) {
113       if (strcmp (name, lamp_iter->id.name+2) == 0) {
114         wanted_lamp = (C_Lamp *)PyObject_NEW(C_Lamp, &Lamp_Type);
115                                 if (wanted_lamp) wanted_lamp->lamp = lamp_iter;
116       }
117       lamp_iter = lamp_iter->id.next;
118     }
119
120     if (wanted_lamp == NULL) { /* Requested lamp doesn't exist */
121       char error_msg[64];
122       PyOS_snprintf(error_msg, sizeof(error_msg),
123                       "Lamp \"%s\" not found", name);
124       return (EXPP_ReturnPyObjError (PyExc_NameError, error_msg));
125     }
126
127     return (PyObject *)wanted_lamp;
128         }
129
130         else { /* () - return a list of all lamps in the scene */
131     int index = 0;
132     PyObject *lamplist, *pystr;
133
134     lamplist = PyList_New (BLI_countlist (&(G.main->lamp)));
135
136     if (lamplist == NULL)
137       return (PythonReturnErrorObject (PyExc_MemoryError,
138               "couldn't create PyList"));
139
140                 while (lamp_iter) {
141       pystr = PyString_FromString (lamp_iter->id.name+2);
142
143                         if (!pystr)
144                                 return (PythonReturnErrorObject (PyExc_MemoryError,
145                                                                         "couldn't create PyString"));
146
147                         PyList_SET_ITEM (lamplist, index, pystr);
148
149       lamp_iter = lamp_iter->id.next;
150       index++;
151                 }
152
153                 return (lamplist);
154         }
155 }
156
157 /*****************************************************************************/
158 /* Function:              M_Lamp_Init                                        */
159 /*****************************************************************************/
160 PyObject *M_Lamp_Init (void)
161 {
162   PyObject  *submodule;
163
164   printf ("In M_Lamp_Init()\n");
165
166   submodule = Py_InitModule3("Blender.Lamp", M_Lamp_methods, M_Lamp_doc);
167
168   return (submodule);
169 }
170
171 /*****************************************************************************/
172 /* Python C_Lamp methods:                                                    */
173 /*****************************************************************************/
174 static PyObject *Lamp_getName(C_Lamp *self)
175 {
176   PyObject *attr = PyString_FromString(self->lamp->id.name+2);
177
178   if (attr) return attr;
179
180   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
181           "couldn't get Lamp.name attribute"));
182 }
183
184 static PyObject *Lamp_getType(C_Lamp *self)
185
186   PyObject *attr = PyInt_FromLong(self->lamp->type);
187
188   if (attr) return attr;
189
190   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
191           "couldn't get Lamp.type attribute"));
192 }
193
194 static PyObject *Lamp_getMode(C_Lamp *self)
195 {
196   PyObject *attr = PyInt_FromLong(self->lamp->mode);
197
198   if (attr) return attr;
199
200   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
201           "couldn't get Lamp.mode attribute"));
202 }
203
204 static PyObject *Lamp_getSamples(C_Lamp *self)
205 {
206   PyObject *attr = PyInt_FromLong(self->lamp->samp);
207
208   if (attr) return attr;
209
210   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
211           "couldn't get Lamp.samples attribute"));
212 }
213
214 static PyObject *Lamp_getBufferSize(C_Lamp *self)
215 {
216   PyObject *attr = PyInt_FromLong(self->lamp->bufsize);
217
218   if (attr) return attr;
219
220   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
221           "couldn't get Lamp.bufferSize attribute"));
222 }
223
224 static PyObject *Lamp_getHaloStep(C_Lamp *self)
225 {
226   PyObject *attr = PyInt_FromLong(self->lamp->shadhalostep);
227
228   if (attr) return attr;
229
230   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
231           "couldn't get Lamp.haloStep attribute"));
232 }
233
234 static PyObject *Lamp_getEnergy(C_Lamp *self)
235 {
236   PyObject *attr = PyFloat_FromDouble(self->lamp->energy);
237
238   if (attr) return attr;
239
240   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
241           "couldn't get Lamp.energy attribute"));
242 }
243
244 static PyObject *Lamp_getDist(C_Lamp *self)
245 {
246   PyObject *attr = PyFloat_FromDouble(self->lamp->dist);
247
248   if (attr) return attr;
249
250   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
251           "couldn't get Lamp.dist attribute"));
252 }
253
254 static PyObject *Lamp_getSpotSize(C_Lamp *self)
255 {
256   PyObject *attr = PyFloat_FromDouble(self->lamp->spotsize);
257
258   if (attr) return attr;
259
260   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
261           "couldn't get Lamp.spotSize attribute"));
262 }
263
264 static PyObject *Lamp_getSpotBlend(C_Lamp *self)
265 {
266   PyObject *attr = PyFloat_FromDouble(self->lamp->spotblend);
267
268   if (attr) return attr;
269
270   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
271           "couldn't get Lamp.spotBlend attribute"));
272 }
273
274 static PyObject *Lamp_getClipStart(C_Lamp *self)
275 {
276   PyObject *attr = PyFloat_FromDouble(self->lamp->clipsta);
277
278   if (attr) return attr;
279
280   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
281           "couldn't get Lamp.clipStart attribute"));
282 }
283
284 static PyObject *Lamp_getClipEnd(C_Lamp *self)
285 {
286   PyObject *attr = PyFloat_FromDouble(self->lamp->clipend);
287
288   if (attr) return attr;
289
290   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
291           "couldn't get Lamp.clipEnd attribute"));
292 }
293
294 static PyObject *Lamp_getBias(C_Lamp *self)
295 {
296   PyObject *attr = PyFloat_FromDouble(self->lamp->bias);
297
298   if (attr) return attr;
299
300   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
301           "couldn't get Lamp.bias attribute"));
302 }
303
304 static PyObject *Lamp_getSoftness(C_Lamp *self)
305 {
306   PyObject *attr = PyFloat_FromDouble(self->lamp->soft);
307
308   if (attr) return attr;
309
310   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
311           "couldn't get Lamp.softness attribute"));
312 }
313
314 static PyObject *Lamp_getHaloInt(C_Lamp *self)
315 {
316   PyObject *attr = PyFloat_FromDouble(self->lamp->haint);
317
318   if (attr) return attr;
319
320   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
321           "couldn't get Lamp.haloInt attribute"));
322 }
323
324 static PyObject *Lamp_getQuad1(C_Lamp *self)
325 { /* should we complain if Lamp is not of type Quad? */
326   PyObject *attr = PyFloat_FromDouble(self->lamp->att1);
327
328   if (attr) return attr;
329
330   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
331           "couldn't get Lamp.quad1 attribute"));
332 }
333
334 static PyObject *Lamp_getQuad2(C_Lamp *self)
335 { /* should we complain if Lamp is not of type Quad? */
336   PyObject *attr = PyFloat_FromDouble(self->lamp->att2);
337
338   if (attr) return attr;
339
340   return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
341           "couldn't get Lamp.quad2 attribute"));
342 }
343
344 static PyObject *Lamp_rename(C_Lamp *self, PyObject *args)
345 {
346   char *name;
347   char buf[21];
348
349   if (!PyArg_ParseTuple(args, "s", &name))
350     return (EXPP_ReturnPyObjError (PyExc_TypeError,
351             "expected string argument"));
352   
353   PyOS_snprintf(buf, sizeof(buf), "%s", name);
354
355   rename_id(&self->lamp->id, buf);
356
357   Py_INCREF(Py_None);
358   return Py_None;
359 }
360
361 static PyObject *Lamp_setType(C_Lamp *self, PyObject *args)
362 {
363   char *type;
364
365   if (!PyArg_ParseTuple(args, "s", &type))
366     return (EXPP_ReturnPyObjError (PyExc_TypeError,
367             "expected string argument"));
368
369   if (strcmp (type, "Lamp") == 0)
370     self->lamp->type = (short)EXPP_LAMP_TYPE_LAMP;
371   else if (strcmp (type, "Sun") == 0)
372     self->lamp->type = (short)EXPP_LAMP_TYPE_SUN; 
373   else if (strcmp (type, "Spot") == 0)
374     self->lamp->type = (short)EXPP_LAMP_TYPE_SPOT;  
375   else if (strcmp (type, "Hemi") == 0)
376     self->lamp->type = (short)EXPP_LAMP_TYPE_HEMI;  
377   else
378     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
379             "unknown lamp type"));
380
381   Py_INCREF(Py_None);
382   return Py_None;
383 }
384
385 /* This one is 'private'. It is not really a method, just a helper function for
386  * when script writers use Lamp.type = t instead of Lamp.setType(t), since in
387  * the first case t shoud be an int and in the second it should be a string. So
388  * while the method setType expects a string ('persp' or 'ortho') or an empty
389  * argument, this function should receive an int (0 or 1). */
390 static PyObject *Lamp_setIntType(C_Lamp *self, PyObject *args)
391 {
392   short value;
393
394   if (!PyArg_ParseTuple(args, "h", &value))
395     return (EXPP_ReturnPyObjError (PyExc_TypeError,
396             "expected int argument in [0,3]"));
397
398   if (value >= 0 && value <= 3)
399     self->lamp->type = value;
400   else
401     return (EXPP_ReturnPyObjError (PyExc_ValueError,
402             "expected int argument in [0,3]"));
403
404   Py_INCREF(Py_None);
405   return Py_None;
406 }
407
408 static PyObject *Lamp_setMode(C_Lamp *self, PyObject *args)
409 {/* Quad, Sphere, Shadows, Halo, Layer, Negative, OnlyShadow, Square */
410   char *m[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
411   short i, flag = 0;
412
413   if (!PyArg_ParseTuple(args, "|ssssssss", &m[0], &m[1], &m[2],
414                         &m[3], &m[4], &m[5], &m[6], &m[7]))
415     return (EXPP_ReturnPyObjError (PyExc_AttributeError,
416             "expected from none to eight string argument(s)"));
417
418   for (i = 0; i < 8; i++) {
419     if (m[i] == NULL) break;
420     if (strcmp(m[i], "Shadows") == 0)
421       flag |= (short)EXPP_LAMP_MODE_SHADOWS;
422     else if (strcmp(m[i], "Halo") == 0)
423       flag |= (short)EXPP_LAMP_MODE_HALO;
424     else if (strcmp(m[i], "Layer") == 0)
425       flag |= (short)EXPP_LAMP_MODE_LAYER;
426     else if (strcmp(m[i], "Quad") == 0)
427       flag |= (short)EXPP_LAMP_MODE_QUAD;
428     else if (strcmp(m[i], "Negative") == 0)
429       flag |= (short)EXPP_LAMP_MODE_NEGATIVE;
430     else if (strcmp(m[i], "OnlyShadow") == 0)
431       flag |= (short)EXPP_LAMP_MODE_ONLYSHADOW;
432     else if (strcmp(m[i], "Sphere") == 0)
433       flag |= (short)EXPP_LAMP_MODE_SPHERE;
434     else if (strcmp(m[i], "Square") == 0)
435       flag |= (short)EXPP_LAMP_MODE_SQUARE;
436     else
437       return (EXPP_ReturnPyObjError (PyExc_AttributeError,
438               "unknown lamp flag argument"));
439   }
440
441   self->lamp->mode = flag;
442
443   Py_INCREF(Py_None);
444   return Py_None;
445 }
446
447 /* Another helper function, for the same reason.
448  * (See comment before Lamp_setIntType above). */
449 static PyObject *Lamp_setIntMode(C_Lamp *self, PyObject *args)
450 {
451   short value;
452
453   if (!PyArg_ParseTuple(args, "h", &value))
454     return (EXPP_ReturnPyObjError (PyExc_TypeError,
455             "expected int argument"));
456
457 /* well, with so many flag bits, we just accept any short int, no checking */
458   self->lamp->mode = value;
459
460   Py_INCREF(Py_None);
461   return Py_None;
462 }
463
464 static PyObject *Lamp_setSamples(C_Lamp *self, PyObject *args)
465 {
466   short value;
467
468   if (!PyArg_ParseTuple(args, "h", &value))
469     return (EXPP_ReturnPyObjError (PyExc_TypeError,
470             "expected int argument in [1,16]"));
471
472   if (value >= EXPP_LAMP_SAMPLES_MIN &&
473       value <= EXPP_LAMP_SAMPLES_MAX)
474     self->lamp->samp = value;
475   else
476     return (EXPP_ReturnPyObjError (PyExc_ValueError,
477             "expected int argument in [1,16]"));
478
479   Py_INCREF(Py_None);
480   return Py_None;
481 }
482
483 static PyObject *Lamp_setBufferSize(C_Lamp *self, PyObject *args)
484 {
485   short value;
486
487   if (!PyArg_ParseTuple(args, "h", &value))
488     return (EXPP_ReturnPyObjError (PyExc_TypeError,
489             "expected int argument in [512, 5120]"));
490         
491   if (value >= EXPP_LAMP_BUFFERSIZE_MIN &&
492       value <= EXPP_LAMP_BUFFERSIZE_MAX)
493     self->lamp->bufsize = value;
494   else
495     return (EXPP_ReturnPyObjError (PyExc_ValueError,
496             "expected int argument in [512, 5120]"));
497
498   Py_INCREF(Py_None);
499   return Py_None;
500 }
501
502 static PyObject *Lamp_setHaloStep(C_Lamp *self, PyObject *args)
503 {
504   short value;
505
506   if (!PyArg_ParseTuple(args, "h", &value))
507     return (EXPP_ReturnPyObjError (PyExc_TypeError,
508             "expected int argument in [0,12]"));
509
510   if (value >= EXPP_LAMP_HALOSTEP_MIN &&
511       value <= EXPP_LAMP_HALOSTEP_MAX)
512     self->lamp->shadhalostep = value;
513   else
514     return (EXPP_ReturnPyObjError (PyExc_ValueError,
515             "expected int argument in [0,12]"));
516
517   Py_INCREF(Py_None);
518   return Py_None;
519 }
520
521 static PyObject *Lamp_setColorComponent(C_Lamp *self, char *key, PyObject *args)
522 {
523   float value;
524   
525   if (!PyArg_ParseTuple(args, "f", &value))
526     return (EXPP_ReturnPyObjError (PyExc_TypeError,
527             "expected float argument in [0.0, 1.0]"));
528
529   value = EXPP_ClampFloat (value, 0.0, 1.0);
530     
531   if (!strcmp(key, "R"))
532     self->lamp->r = value;
533   else if (!strcmp(key, "G"))
534     self->lamp->g = value;
535   else if (!strcmp(key, "B"))
536     self->lamp->b = value;
537
538   Py_INCREF(Py_None);
539   return Py_None;
540 }
541
542 static PyObject *Lamp_setEnergy(C_Lamp *self, PyObject *args)
543 {
544   float value;
545   
546   if (!PyArg_ParseTuple(args, "f", &value))
547     return (EXPP_ReturnPyObjError (PyExc_TypeError,
548             "expected float argument"));
549
550   value = EXPP_ClampFloat (value, EXPP_LAMP_ENERGY_MIN, EXPP_LAMP_ENERGY_MAX);
551   self->lamp->energy = value;
552
553   Py_INCREF(Py_None);
554   return Py_None;
555 }
556
557 static PyObject *Lamp_setDist(C_Lamp *self, PyObject *args)
558 {
559   float value;
560   
561   if (!PyArg_ParseTuple(args, "f", &value))
562     return (EXPP_ReturnPyObjError (PyExc_TypeError,
563             "expected float argument"));
564
565   value = EXPP_ClampFloat (value, EXPP_LAMP_DIST_MIN, EXPP_LAMP_DIST_MAX);
566   self->lamp->dist = value;
567
568   Py_INCREF(Py_None);
569   return Py_None;
570 }
571
572 static PyObject *Lamp_setSpotSize(C_Lamp *self, PyObject *args)
573 {
574   float value;
575   
576   if (!PyArg_ParseTuple(args, "f", &value))
577     return (EXPP_ReturnPyObjError (PyExc_TypeError,
578             "expected float argument"));
579
580   value = EXPP_ClampFloat (value, EXPP_LAMP_SPOTSIZE_MIN,
581                                                                         EXPP_LAMP_SPOTSIZE_MAX);
582   self->lamp->spotsize = value;
583
584   Py_INCREF(Py_None);
585   return Py_None;
586 }
587
588 static PyObject *Lamp_setSpotBlend(C_Lamp *self, PyObject *args)
589 {
590   float value;
591   
592   if (!PyArg_ParseTuple(args, "f", &value))
593     return (EXPP_ReturnPyObjError (PyExc_TypeError,
594             "expected float argument"));
595
596   value = EXPP_ClampFloat (value, EXPP_LAMP_SPOTBLEND_MIN,
597                   EXPP_LAMP_SPOTBLEND_MAX);
598   self->lamp->spotblend = value;
599
600   Py_INCREF(Py_None);
601   return Py_None;
602 }
603
604 static PyObject *Lamp_setClipStart(C_Lamp *self, PyObject *args)
605 {
606   float value;
607   
608   if (!PyArg_ParseTuple(args, "f", &value))
609     return (EXPP_ReturnPyObjError (PyExc_TypeError,
610             "expected float argument"));
611   
612   value = EXPP_ClampFloat (value, EXPP_LAMP_CLIPSTART_MIN,
613                   EXPP_LAMP_CLIPSTART_MAX);
614   self->lamp->clipsta = value;
615
616   Py_INCREF(Py_None);
617   return Py_None;
618 }
619
620 static PyObject *Lamp_setClipEnd(C_Lamp *self, PyObject *args)
621 {
622   float value;
623
624   if (!PyArg_ParseTuple(args, "f", &value))
625     return (EXPP_ReturnPyObjError (PyExc_TypeError,
626             "expected float argument"));
627
628   value = EXPP_ClampFloat (value, EXPP_LAMP_CLIPEND_MIN,
629                   EXPP_LAMP_CLIPEND_MAX);
630   self->lamp->clipend = value;
631
632   Py_INCREF(Py_None);
633   return Py_None;
634 }
635
636 static PyObject *Lamp_setBias(C_Lamp *self, PyObject *args)
637 {
638   float value;
639   
640   if (!PyArg_ParseTuple(args, "f", &value))
641     return (EXPP_ReturnPyObjError (PyExc_TypeError,
642             "expected float argument"));
643
644   value = EXPP_ClampFloat (value, EXPP_LAMP_BIAS_MIN, EXPP_LAMP_BIAS_MAX);
645   self->lamp->bias = value;
646
647   Py_INCREF(Py_None);
648   return Py_None;
649 }
650
651 static PyObject *Lamp_setSoftness(C_Lamp *self, PyObject *args)
652 {
653   float value;
654   
655   if (!PyArg_ParseTuple(args, "f", &value))
656     return (EXPP_ReturnPyObjError (PyExc_TypeError,
657             "expected float argument"));
658
659   value = EXPP_ClampFloat (value, EXPP_LAMP_SOFTNESS_MIN,
660                   EXPP_LAMP_SOFTNESS_MAX);
661   self->lamp->soft = value;
662
663   Py_INCREF(Py_None);
664   return Py_None;
665 }
666
667 static PyObject *Lamp_setHaloInt(C_Lamp *self, PyObject *args)
668 {
669   float value;
670
671   if (!PyArg_ParseTuple(args, "f", &value))
672     return (EXPP_ReturnPyObjError (PyExc_TypeError,
673             "expected float argument"));
674
675   value = EXPP_ClampFloat (value, EXPP_LAMP_HALOINT_MIN,
676                   EXPP_LAMP_HALOINT_MAX);
677   self->lamp->haint = value;
678
679   Py_INCREF(Py_None);
680   return Py_None;
681 }
682
683 static PyObject *Lamp_setQuad1(C_Lamp *self, PyObject *args)
684 {
685   float value;
686
687   if (!PyArg_ParseTuple(args, "f", &value))
688     return (EXPP_ReturnPyObjError (PyExc_TypeError,
689             "expected float argument"));
690
691   value = EXPP_ClampFloat (value, EXPP_LAMP_QUAD1_MIN,
692                   EXPP_LAMP_QUAD1_MAX);
693   self->lamp->att1 = value;
694
695   Py_INCREF(Py_None);
696   return Py_None;
697 }
698
699 static PyObject *Lamp_setQuad2(C_Lamp *self, PyObject *args)
700 {
701   float value;
702
703   if (!PyArg_ParseTuple(args, "f", &value))
704     return (EXPP_ReturnPyObjError (PyExc_TypeError,
705             "expected float argument"));
706
707   value = EXPP_ClampFloat (value, EXPP_LAMP_QUAD2_MIN,
708                   EXPP_LAMP_QUAD2_MAX);
709   self->lamp->att2 = value;
710
711   Py_INCREF(Py_None);
712   return Py_None;
713 }
714
715 /*****************************************************************************/
716 /* Function:    LampDeAlloc                                                  */
717 /* Description: This is a callback function for the C_Lamp type. It is       */
718 /*              the destructor function.                                     */
719 /*****************************************************************************/
720 static void LampDeAlloc (C_Lamp *self)
721 {
722   PyObject_DEL (self);
723 }
724
725 /*****************************************************************************/
726 /* Function:    LampGetAttr                                                  */
727 /* Description: This is a callback function for the C_Lamp type. It is       */
728 /*              the function that accesses C_Lamp member variables and       */
729 /*              methods.                                                     */
730 /*****************************************************************************/
731 static PyObject* LampGetAttr (C_Lamp *self, char *name)
732 {
733   PyObject *attr = Py_None;
734
735   if (strcmp(name, "name") == 0)
736     attr = PyString_FromString(self->lamp->id.name+2);
737   else if (strcmp(name, "type") == 0)
738     attr = PyInt_FromLong(self->lamp->type);
739   else if (strcmp(name, "mode") == 0)
740     attr = PyInt_FromLong(self->lamp->mode);
741   else if (strcmp(name, "samples") == 0)
742     attr = PyInt_FromLong(self->lamp->samp);
743   else if (strcmp(name, "bufferSize") == 0)
744     attr = PyInt_FromLong(self->lamp->bufsize);
745   else if (strcmp(name, "haloStep") == 0)
746     attr = PyInt_FromLong(self->lamp->shadhalostep);
747   else if (strcmp(name, "R") == 0)
748     attr = PyFloat_FromDouble(self->lamp->r);
749   else if (strcmp(name, "G") == 0)
750     attr = PyFloat_FromDouble(self->lamp->g);
751   else if (strcmp(name, "B") == 0)
752     attr = PyFloat_FromDouble(self->lamp->b);
753   else if (strcmp(name, "energy") == 0)
754     attr = PyFloat_FromDouble(self->lamp->energy);
755   else if (strcmp(name, "dist") == 0)
756     attr = PyFloat_FromDouble(self->lamp->dist);
757   else if (strcmp(name, "spotSize") == 0)
758     attr = PyFloat_FromDouble(self->lamp->spotsize);
759   else if (strcmp(name, "spotBlend") == 0)
760     attr = PyFloat_FromDouble(self->lamp->spotblend);
761   else if (strcmp(name, "clipStart") == 0)
762     attr = PyFloat_FromDouble(self->lamp->clipsta);
763   else if (strcmp(name, "clipEnd") == 0)
764     attr = PyFloat_FromDouble(self->lamp->clipend);
765   else if (strcmp(name, "bias") == 0)
766     attr = PyFloat_FromDouble(self->lamp->bias);
767   else if (strcmp(name, "softness") == 0)
768     attr = PyFloat_FromDouble(self->lamp->soft);
769   else if (strcmp(name, "haloInt") == 0)
770     attr = PyFloat_FromDouble(self->lamp->haint);
771   else if (strcmp(name, "quad1") == 0)
772     attr = PyFloat_FromDouble(self->lamp->att1);
773   else if (strcmp(name, "quad2") == 0)
774     attr = PyFloat_FromDouble(self->lamp->att2);
775
776   else if (strcmp(name, "Types") == 0) {
777     attr = Py_BuildValue("{s:h,s:h,s:h,s:h}",
778                     "Lamp", EXPP_LAMP_TYPE_LAMP,
779                     "Sun" , EXPP_LAMP_TYPE_SUN,
780                     "Spot", EXPP_LAMP_TYPE_SPOT,
781                     "Hemi", EXPP_LAMP_TYPE_HEMI);
782   }
783
784   else if (strcmp(name, "Modes") == 0) {
785     attr = Py_BuildValue("{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
786                     "Shadows",    EXPP_LAMP_MODE_SHADOWS,
787                     "Halo",       EXPP_LAMP_MODE_HALO,
788                     "Layer",      EXPP_LAMP_MODE_LAYER,
789                     "Quad",       EXPP_LAMP_MODE_QUAD,
790                     "Negative",   EXPP_LAMP_MODE_NEGATIVE,
791                     "OnlyShadow", EXPP_LAMP_MODE_ONLYSHADOW,
792                     "Sphere",     EXPP_LAMP_MODE_SPHERE,
793                     "Square",     EXPP_LAMP_MODE_SQUARE);
794   }
795
796   else if (strcmp(name, "__members__") == 0) {
797     /* 22 entries */
798     attr = Py_BuildValue("[s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s]",
799                     "name", "type", "mode", "samples", "bufferSize",
800                     "haloStep", "R", "G", "B", "energy", "dist",
801                     "spotSize", "spotBlend", "clipStart", "clipEnd",
802                     "bias", "softness", "haloInt", "quad1", "quad2",
803                     "Types", "Modes");
804   }
805
806   if (!attr)
807     return (EXPP_ReturnPyObjError (PyExc_MemoryError,
808                       "couldn't create PyObject"));
809
810   if (attr != Py_None) return attr; /* member attribute found, return it */
811
812   /* not an attribute, search the methods table */
813   return Py_FindMethod(C_Lamp_methods, (PyObject *)self, name);
814 }
815
816 /*****************************************************************************/
817 /* Function:    LampSetAttr                                                  */
818 /* Description: This is a callback function for the C_Lamp type. It is the   */
819 /*              function that changes Lamp Data members values. If this      */
820 /*              data is linked to a Blender Lamp, it also gets updated.      */
821 /*****************************************************************************/
822 static int LampSetAttr (C_Lamp *self, char *name, PyObject *value)
823 {
824   PyObject *valtuple; 
825   PyObject *error = NULL;
826
827   valtuple = Py_BuildValue("(N)", value); /* the set* functions expect a tuple */
828
829   if (!valtuple)
830     return EXPP_ReturnIntError(PyExc_MemoryError,
831                   "LampSetAttr: couldn't create tuple");
832
833   if (strcmp (name, "name") == 0)
834     error = Lamp_rename (self, valtuple);
835   else if (strcmp (name, "type") == 0)
836     error = Lamp_setIntType (self, valtuple); /* special case */
837   else if (strcmp (name, "mode") == 0)
838     error = Lamp_setIntMode (self, valtuple); /* special case */
839   else if (strcmp (name, "samples") == 0)
840     error = Lamp_setSamples (self, valtuple);
841   else if (strcmp (name, "bufferSize") == 0)
842     error = Lamp_setBufferSize (self, valtuple);
843   else if (strcmp (name, "haloStep") == 0)
844     error = Lamp_setHaloStep (self, valtuple);
845   else if (strcmp (name, "R") == 0)
846     error = Lamp_setColorComponent (self, "R", valtuple);
847   else if (strcmp (name, "G") == 0)
848     error = Lamp_setColorComponent (self, "G", valtuple);
849   else if (strcmp (name, "B") == 0)
850     error = Lamp_setColorComponent (self, "B", valtuple);
851   else if (strcmp (name, "energy") == 0)
852     error = Lamp_setEnergy (self, valtuple);
853   else if (strcmp (name, "dist") == 0)
854     error = Lamp_setDist (self, valtuple);
855   else if (strcmp (name, "spotSize") == 0)
856     error = Lamp_setSpotSize (self, valtuple);
857   else if (strcmp (name, "spotBlend") == 0)
858     error = Lamp_setSpotBlend (self, valtuple);
859   else if (strcmp (name, "clipStart") == 0)
860     error = Lamp_setClipStart (self, valtuple);
861   else if (strcmp (name, "clipEnd") == 0)
862     error = Lamp_setClipEnd (self, valtuple);
863   else if (strcmp (name, "bias") == 0)
864     error = Lamp_setBias (self, valtuple);
865   else if (strcmp (name, "softness") == 0)
866     error = Lamp_setSoftness (self, valtuple);
867   else if (strcmp (name, "haloInt") == 0)
868     error = Lamp_setHaloInt (self, valtuple);
869   else if (strcmp (name, "quad1") == 0)
870     error = Lamp_setQuad1 (self, valtuple);
871   else if (strcmp (name, "quad2") == 0)
872     error = Lamp_setQuad2 (self, valtuple);
873   
874   else { /* Error */
875     Py_DECREF(valtuple);
876   
877     if ((strcmp (name, "Types") == 0) || /* user tried to change a */
878         (strcmp (name, "Modes") == 0))   /* constant dict type ... */
879       return (EXPP_ReturnIntError (PyExc_AttributeError,
880                    "constant dictionary -- cannot be changed"));
881
882     else /* ... or no member with the given name was found */
883       return (EXPP_ReturnIntError (PyExc_KeyError,
884                    "attribute not found"));
885   }
886
887   Py_DECREF(valtuple);
888   
889   if (error != Py_None) return -1;
890
891   Py_DECREF(Py_None); /* was incref'ed by the called Lamp_set* function */
892   return 0; /* normal exit */
893 }
894
895 /*****************************************************************************/
896 /* Function:    LampPrint                                                    */
897 /* Description: This is a callback function for the C_Lamp type. It          */
898 /*              builds a meaninful string to 'print' lamp objects.           */
899 /*****************************************************************************/
900 static int LampPrint(C_Lamp *self, FILE *fp, int flags)
901
902   fprintf(fp, "[Lamp \"%s\"]", self->lamp->id.name+2);
903   return 0;
904 }
905
906 /*****************************************************************************/
907 /* Function:    LampRepr                                                     */
908 /* Description: This is a callback function for the C_Lamp type. It          */
909 /*              builds a meaninful string to represent lamp objects.         */
910 /*****************************************************************************/
911 static PyObject *LampRepr (C_Lamp *self)
912 {
913   return PyString_FromString(self->lamp->id.name+2);
914 }