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 (11 years, 11 months 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: mgf_context.c,v 3.1 2011/02/18 00:40:25 greg Exp $";
3 #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 static int setspectrum(C_COLOR *, int ac, char **av);
36
37
38 int
39 c_hcolor(int ac, char **av) /* handle color entity */
40 {
41 double w, wsum;
42 int i;
43 LUENT *lp;
44
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 return(setspectrum(c_ccolor, ac-1, av+1));
111 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 LUENT *lp;
157
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 LUENT *lp;
303
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 LUENT *lp;
403
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 LUENT *lp;
414
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 LUENT *lp;
425
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 setspectrum( /* convert a spectrum */
434 C_COLOR *clr,
435 int ac,
436 char **av
437 )
438 {
439 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 return(MG_EILL);
461 }
462 free(va);
463 clr->clock++;
464 return(MG_OK);
465 }