ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/mgf_context.c
Revision: 3.2
Committed: Thu May 17 17:10:23 2012 UTC (12 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad4R2P2, rad5R0, rad5R1, rad4R2, rad4R2P1, rad5R3
Changes since 3.1: +34 -87 lines
Log Message:
Added spectrum assignment function c_sset()

File Contents

# User Rev Content
1 greg 3.1 #ifndef lint
2 greg 3.2 static const char RCSid[] = "$Id: mgf_context.c,v 3.1 2011/02/18 00:40:25 greg Exp $";
3 greg 3.1 #endif
4     /*
5     * Context handlers
6     */
7    
8     #include <stdio.h>
9     #include <stdlib.h>
10     #include <string.h>
11     #include "mgf_parser.h"
12     #include "lookup.h"
13    
14     /* default context values */
15     static C_MATERIAL c_dfmaterial = C_DEFMATERIAL;
16     static C_VERTEX c_dfvertex = C_DEFVERTEX;
17    
18     /* the unnamed contexts */
19     static C_COLOR c_uncolor = C_DEFCOLOR;
20     static C_MATERIAL c_unmaterial = C_DEFMATERIAL;
21     static C_VERTEX c_unvertex = C_DEFVERTEX;
22    
23     /* the current contexts */
24     C_COLOR *c_ccolor = &c_uncolor;
25     char *c_ccname = NULL;
26     C_MATERIAL *c_cmaterial = &c_unmaterial;
27     char *c_cmname = NULL;
28     C_VERTEX *c_cvertex = &c_unvertex;
29     char *c_cvname = NULL;
30    
31     static LUTAB clr_tab = LU_SINIT(free,free); /* color lookup table */
32     static LUTAB mat_tab = LU_SINIT(free,free); /* material lookup table */
33     static LUTAB vtx_tab = LU_SINIT(free,free); /* vertex lookup table */
34    
35 greg 3.2 static int setspectrum(C_COLOR *, int ac, char **av);
36 greg 3.1
37    
38     int
39     c_hcolor(int ac, char **av) /* handle color entity */
40     {
41     double w, wsum;
42 greg 3.2 int i;
43     LUENT *lp;
44 greg 3.1
45     switch (mg_entity(av[0])) {
46     case MG_E_COLOR: /* get/set color context */
47     if (ac > 4)
48     return(MG_EARGC);
49     if (ac == 1) { /* set unnamed color context */
50     c_uncolor = c_dfcolor;
51     c_ccolor = &c_uncolor;
52     c_ccname = NULL;
53     return(MG_OK);
54     }
55     if (!isname(av[1]))
56     return(MG_EILL);
57     lp = lu_find(&clr_tab, av[1]); /* lookup context */
58     if (lp == NULL)
59     return(MG_EMEM);
60     c_ccname = lp->key;
61     c_ccolor = (C_COLOR *)lp->data;
62     if (ac == 2) { /* reestablish previous context */
63     if (c_ccolor == NULL)
64     return(MG_EUNDEF);
65     return(MG_OK);
66     }
67     if (av[2][0] != '=' || av[2][1])
68     return(MG_ETYPE);
69     if (c_ccolor == NULL) { /* create new color context */
70     lp->key = (char *)malloc(strlen(av[1])+1);
71     if (lp->key == NULL)
72     return(MG_EMEM);
73     strcpy(lp->key, av[1]);
74     lp->data = (char *)malloc(sizeof(C_COLOR));
75     if (lp->data == NULL)
76     return(MG_EMEM);
77     c_ccname = lp->key;
78     c_ccolor = (C_COLOR *)lp->data;
79     c_ccolor->clock = 0;
80     c_ccolor->client_data = NULL;
81     }
82     i = c_ccolor->clock;
83     if (ac == 3) { /* use default template */
84     *c_ccolor = c_dfcolor;
85     c_ccolor->clock = i + 1;
86     return(MG_OK);
87     }
88     lp = lu_find(&clr_tab, av[3]); /* lookup template */
89     if (lp == NULL)
90     return(MG_EMEM);
91     if (lp->data == NULL)
92     return(MG_EUNDEF);
93     *c_ccolor = *(C_COLOR *)lp->data;
94     c_ccolor->clock = i + 1;
95     return(MG_OK);
96     case MG_E_CXY: /* assign CIE XY value */
97     if (ac != 3)
98     return(MG_EARGC);
99     if (!isflt(av[1]) | !isflt(av[2]))
100     return(MG_ETYPE);
101     c_ccolor->cx = atof(av[1]);
102     c_ccolor->cy = atof(av[2]);
103     c_ccolor->flags = C_CDXY|C_CSXY;
104     if ((c_ccolor->cx < 0.) | (c_ccolor->cy < 0.) |
105     (c_ccolor->cx + c_ccolor->cy > 1.))
106     return(MG_EILL);
107     c_ccolor->clock++;
108     return(MG_OK);
109     case MG_E_CSPEC: /* assign spectral values */
110 greg 3.2 return(setspectrum(c_ccolor, ac-1, av+1));
111 greg 3.1 case MG_E_CCT: /* assign black body spectrum */
112     if (ac != 2)
113     return(MG_EARGC);
114     if (!isflt(av[1]))
115     return(MG_ETYPE);
116     if (!c_bbtemp(c_ccolor, atof(av[1])))
117     return(MG_EILL);
118     c_ccolor->clock++;
119     return(MG_OK);
120     case MG_E_CMIX: /* mix colors */
121     if (ac < 5 || (ac-1)%2)
122     return(MG_EARGC);
123     if (!isflt(av[1]))
124     return(MG_ETYPE);
125     wsum = atof(av[1]);
126     if ((lp = lu_find(&clr_tab, av[2])) == NULL)
127     return(MG_EMEM);
128     if (lp->data == NULL)
129     return(MG_EUNDEF);
130     *c_ccolor = *(C_COLOR *)lp->data;
131     for (i = 3; i < ac; i += 2) {
132     if (!isflt(av[i]))
133     return(MG_ETYPE);
134     w = atof(av[i]);
135     if ((lp = lu_find(&clr_tab, av[i+1])) == NULL)
136     return(MG_EMEM);
137     if (lp->data == NULL)
138     return(MG_EUNDEF);
139     c_cmix(c_ccolor, wsum, c_ccolor,
140     w, (C_COLOR *)lp->data);
141     wsum += w;
142     }
143     if (wsum <= 0.)
144     return(MG_EILL);
145     c_ccolor->clock++;
146     return(MG_OK);
147     }
148     return(MG_EUNK);
149     }
150    
151    
152     int
153     c_hmaterial(int ac, char **av) /* handle material entity */
154     {
155     int i;
156 greg 3.2 LUENT *lp;
157 greg 3.1
158     switch (mg_entity(av[0])) {
159     case MG_E_MATERIAL: /* get/set material context */
160     if (ac > 4)
161     return(MG_EARGC);
162     if (ac == 1) { /* set unnamed material context */
163     c_unmaterial = c_dfmaterial;
164     c_cmaterial = &c_unmaterial;
165     c_cmname = NULL;
166     return(MG_OK);
167     }
168     if (!isname(av[1]))
169     return(MG_EILL);
170     lp = lu_find(&mat_tab, av[1]); /* lookup context */
171     if (lp == NULL)
172     return(MG_EMEM);
173     c_cmname = lp->key;
174     c_cmaterial = (C_MATERIAL *)lp->data;
175     if (ac == 2) { /* reestablish previous context */
176     if (c_cmaterial == NULL)
177     return(MG_EUNDEF);
178     return(MG_OK);
179     }
180     if (av[2][0] != '=' || av[2][1])
181     return(MG_ETYPE);
182     if (c_cmaterial == NULL) { /* create new material */
183     lp->key = (char *)malloc(strlen(av[1])+1);
184     if (lp->key == NULL)
185     return(MG_EMEM);
186     strcpy(lp->key, av[1]);
187     lp->data = (char *)malloc(sizeof(C_MATERIAL));
188     if (lp->data == NULL)
189     return(MG_EMEM);
190     c_cmname = lp->key;
191     c_cmaterial = (C_MATERIAL *)lp->data;
192     c_cmaterial->clock = 0;
193     c_cmaterial->client_data = NULL;
194     }
195     i = c_cmaterial->clock;
196     if (ac == 3) { /* use default template */
197     *c_cmaterial = c_dfmaterial;
198     c_cmaterial->clock = i + 1;
199     return(MG_OK);
200     }
201     lp = lu_find(&mat_tab, av[3]); /* lookup template */
202     if (lp == NULL)
203     return(MG_EMEM);
204     if (lp->data == NULL)
205     return(MG_EUNDEF);
206     *c_cmaterial = *(C_MATERIAL *)lp->data;
207     c_cmaterial->clock = i + 1;
208     return(MG_OK);
209     case MG_E_IR: /* set index of refraction */
210     if (ac != 3)
211     return(MG_EARGC);
212     if (!isflt(av[1]) | !isflt(av[2]))
213     return(MG_ETYPE);
214     c_cmaterial->nr = atof(av[1]);
215     c_cmaterial->ni = atof(av[2]);
216     if (c_cmaterial->nr <= FTINY)
217     return(MG_EILL);
218     c_cmaterial->clock++;
219     return(MG_OK);
220     case MG_E_RD: /* set diffuse reflectance */
221     if (ac != 2)
222     return(MG_EARGC);
223     if (!isflt(av[1]))
224     return(MG_ETYPE);
225     c_cmaterial->rd = atof(av[1]);
226     if ((c_cmaterial->rd < 0.) | (c_cmaterial->rd > 1.))
227     return(MG_EILL);
228     c_cmaterial->rd_c = *c_ccolor;
229     c_cmaterial->clock++;
230     return(MG_OK);
231     case MG_E_ED: /* set diffuse emittance */
232     if (ac != 2)
233     return(MG_EARGC);
234     if (!isflt(av[1]))
235     return(MG_ETYPE);
236     c_cmaterial->ed = atof(av[1]);
237     if (c_cmaterial->ed < 0.)
238     return(MG_EILL);
239     c_cmaterial->ed_c = *c_ccolor;
240     c_cmaterial->clock++;
241     return(MG_OK);
242     case MG_E_TD: /* set diffuse transmittance */
243     if (ac != 2)
244     return(MG_EARGC);
245     if (!isflt(av[1]))
246     return(MG_ETYPE);
247     c_cmaterial->td = atof(av[1]);
248     if ((c_cmaterial->td < 0.) | (c_cmaterial->td > 1.))
249     return(MG_EILL);
250     c_cmaterial->td_c = *c_ccolor;
251     c_cmaterial->clock++;
252     return(MG_OK);
253     case MG_E_RS: /* set specular reflectance */
254     if (ac != 3)
255     return(MG_EARGC);
256     if (!isflt(av[1]) | !isflt(av[2]))
257     return(MG_ETYPE);
258     c_cmaterial->rs = atof(av[1]);
259     c_cmaterial->rs_a = atof(av[2]);
260     if ((c_cmaterial->rs < 0.) | (c_cmaterial->rs > 1.) |
261     (c_cmaterial->rs_a < 0.))
262     return(MG_EILL);
263     c_cmaterial->rs_c = *c_ccolor;
264     c_cmaterial->clock++;
265     return(MG_OK);
266     case MG_E_TS: /* set specular transmittance */
267     if (ac != 3)
268     return(MG_EARGC);
269     if (!isflt(av[1]) | !isflt(av[2]))
270     return(MG_ETYPE);
271     c_cmaterial->ts = atof(av[1]);
272     c_cmaterial->ts_a = atof(av[2]);
273     if ((c_cmaterial->ts < 0.) | (c_cmaterial->ts > 1.) |
274     (c_cmaterial->ts_a < 0.))
275     return(MG_EILL);
276     c_cmaterial->ts_c = *c_ccolor;
277     c_cmaterial->clock++;
278     return(MG_OK);
279     case MG_E_SIDES: /* set number of sides */
280     if (ac != 2)
281     return(MG_EARGC);
282     if (!isint(av[1]))
283     return(MG_ETYPE);
284     i = atoi(av[1]);
285     if (i == 1)
286     c_cmaterial->sided = 1;
287     else if (i == 2)
288     c_cmaterial->sided = 0;
289     else
290     return(MG_EILL);
291     c_cmaterial->clock++;
292     return(MG_OK);
293     }
294     return(MG_EUNK);
295     }
296    
297    
298     int
299     c_hvertex(int ac, char **av) /* handle a vertex entity */
300     {
301     int i;
302 greg 3.2 LUENT *lp;
303 greg 3.1
304     switch (mg_entity(av[0])) {
305     case MG_E_VERTEX: /* get/set vertex context */
306     if (ac > 4)
307     return(MG_EARGC);
308     if (ac == 1) { /* set unnamed vertex context */
309     c_unvertex = c_dfvertex;
310     c_cvertex = &c_unvertex;
311     c_cvname = NULL;
312     return(MG_OK);
313     }
314     if (!isname(av[1]))
315     return(MG_EILL);
316     lp = lu_find(&vtx_tab, av[1]); /* lookup context */
317     if (lp == NULL)
318     return(MG_EMEM);
319     c_cvname = lp->key;
320     c_cvertex = (C_VERTEX *)lp->data;
321     if (ac == 2) { /* reestablish previous context */
322     if (c_cvertex == NULL)
323     return(MG_EUNDEF);
324     return(MG_OK);
325     }
326     if (av[2][0] != '=' || av[2][1])
327     return(MG_ETYPE);
328     if (c_cvertex == NULL) { /* create new vertex context */
329     lp->key = (char *)malloc(strlen(av[1])+1);
330     if (lp->key == NULL)
331     return(MG_EMEM);
332     strcpy(lp->key, av[1]);
333     lp->data = (char *)malloc(sizeof(C_VERTEX));
334     if (lp->data == NULL)
335     return(MG_EMEM);
336     c_cvname = lp->key;
337     c_cvertex = (C_VERTEX *)lp->data;
338     c_cvertex->clock = 0;
339     c_cvertex->client_data = NULL;
340     }
341     i = c_cvertex->clock;
342     if (ac == 3) { /* use default template */
343     *c_cvertex = c_dfvertex;
344     c_cvertex->clock = i + 1;
345     return(MG_OK);
346     }
347     lp = lu_find(&vtx_tab, av[3]); /* lookup template */
348     if (lp == NULL)
349     return(MG_EMEM);
350     if (lp->data == NULL)
351     return(MG_EUNDEF);
352     *c_cvertex = *(C_VERTEX *)lp->data;
353     c_cvertex->clock = i + 1;
354     return(MG_OK);
355     case MG_E_POINT: /* set point */
356     if (ac != 4)
357     return(MG_EARGC);
358     if (!isflt(av[1]) | !isflt(av[2]) | !isflt(av[3]))
359     return(MG_ETYPE);
360     c_cvertex->p[0] = atof(av[1]);
361     c_cvertex->p[1] = atof(av[2]);
362     c_cvertex->p[2] = atof(av[3]);
363     c_cvertex->clock++;
364     return(MG_OK);
365     case MG_E_NORMAL: /* set normal */
366     if (ac != 4)
367     return(MG_EARGC);
368     if (!isflt(av[1]) | !isflt(av[2]) | !isflt(av[3]))
369     return(MG_ETYPE);
370     c_cvertex->n[0] = atof(av[1]);
371     c_cvertex->n[1] = atof(av[2]);
372     c_cvertex->n[2] = atof(av[3]);
373     (void)normalize(c_cvertex->n);
374     c_cvertex->clock++;
375     return(MG_OK);
376     }
377     return(MG_EUNK);
378     }
379    
380    
381     void
382     c_clearall(void) /* empty context tables */
383     {
384     c_uncolor = c_dfcolor;
385     c_ccolor = &c_uncolor;
386     c_ccname = NULL;
387     lu_done(&clr_tab);
388     c_unmaterial = c_dfmaterial;
389     c_cmaterial = &c_unmaterial;
390     c_cmname = NULL;
391     lu_done(&mat_tab);
392     c_unvertex = c_dfvertex;
393     c_cvertex = &c_unvertex;
394     c_cvname = NULL;
395     lu_done(&vtx_tab);
396     }
397    
398    
399     C_MATERIAL *
400     c_getmaterial(char *name) /* get a named material */
401     {
402 greg 3.2 LUENT *lp;
403 greg 3.1
404     if ((lp = lu_find(&mat_tab, name)) == NULL)
405     return(NULL);
406     return((C_MATERIAL *)lp->data);
407     }
408    
409    
410     C_VERTEX *
411     c_getvert(char *name) /* get a named vertex */
412     {
413 greg 3.2 LUENT *lp;
414 greg 3.1
415     if ((lp = lu_find(&vtx_tab, name)) == NULL)
416     return(NULL);
417     return((C_VERTEX *)lp->data);
418     }
419    
420    
421     C_COLOR *
422     c_getcolor(char *name) /* get a named color */
423     {
424 greg 3.2 LUENT *lp;
425 greg 3.1
426     if ((lp = lu_find(&clr_tab, name)) == NULL)
427     return(NULL);
428     return((C_COLOR *)lp->data);
429     }
430    
431    
432     static int
433 greg 3.2 setspectrum( /* convert a spectrum */
434     C_COLOR *clr,
435 greg 3.1 int ac,
436     char **av
437     )
438     {
439 greg 3.2 double wlmin, wlmax;
440     int i;
441     float *va;
442     /* get bounds */
443     if (ac < 4)
444     return(MG_EARGC);
445     if (!isflt(av[0]) || !isflt(av[1]))
446     return(MG_ETYPE);
447     wlmin = atof(av[0]);
448     wlmax = atof(av[1]);
449     ac -= 2; av += 2;
450     va = (float *)malloc(sizeof(float)*ac);
451     if (va == NULL)
452     return(MG_EMEM);
453     for (i = ac; i--; ) {
454     if (!isflt(av[i]))
455     return(MG_ETYPE);
456     va[i] = atof(av[i]);
457     }
458     if (c_sset(clr, wlmin, wlmax, va, ac) <= FTINY) {
459     free(va);
460 greg 3.1 return(MG_EILL);
461     }
462 greg 3.2 free(va);
463 greg 3.1 clr->clock++;
464     return(MG_OK);
465     }