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