ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgf2rad.c
Revision: 2.5
Committed: Fri Jul 1 10:20:19 1994 UTC (29 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +2 -2 lines
Log Message:
changed context names from struct members to extern variables

File Contents

# User Rev Content
1 greg 2.1 /* Copyright (c) 1994 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * Convert MGF (Materials and Geometry Format) to Radiance
9     */
10    
11     #include <stdio.h>
12     #include <math.h>
13     #include <string.h>
14     #include "mgflib/parser.h"
15     #include "color.h"
16     #include "tmesh.h"
17    
18     #define putv(v) printf("%18.12g %18.12g %18.12g\n",(v)[0],(v)[1],(v)[2])
19    
20 greg 2.2 double glowdist = FHUGE; /* glow test distance */
21 greg 2.1
22     double emult = 1.; /* emmitter multiplier */
23    
24     int r_comment(), r_cone(), r_cyl(), r_face(), r_ies(), r_ring(), r_sph();
25     char *material(), *object(), *addarg();
26    
27    
28     main(argc, argv) /* convert files to stdout */
29     int argc;
30     char *argv[];
31     {
32     int i, rv;
33     /* initialize dispatch table */
34     mg_ehand[MG_E_COMMENT] = r_comment;
35     mg_ehand[MG_E_COLOR] = c_hcolor;
36     mg_ehand[MG_E_CONE] = r_cone;
37 greg 2.4 mg_ehand[MG_E_CMIX] = c_hcolor;
38     mg_ehand[MG_E_CSPEC] = c_hcolor;
39 greg 2.1 mg_ehand[MG_E_CXY] = c_hcolor;
40     mg_ehand[MG_E_CYL] = r_cyl;
41     mg_ehand[MG_E_ED] = c_hmaterial;
42     mg_ehand[MG_E_FACE] = r_face;
43     mg_ehand[MG_E_IES] = r_ies;
44     mg_ehand[MG_E_MATERIAL] = c_hmaterial;
45     mg_ehand[MG_E_NORMAL] = c_hvertex;
46     mg_ehand[MG_E_OBJECT] = obj_handler;
47     mg_ehand[MG_E_POINT] = c_hvertex;
48     mg_ehand[MG_E_RD] = c_hmaterial;
49     mg_ehand[MG_E_RING] = r_ring;
50     mg_ehand[MG_E_RS] = c_hmaterial;
51     mg_ehand[MG_E_SPH] = r_sph;
52     mg_ehand[MG_E_TD] = c_hmaterial;
53     mg_ehand[MG_E_TS] = c_hmaterial;
54     mg_ehand[MG_E_VERTEX] = c_hvertex;
55     mg_ehand[MG_E_XF] = xf_handler;
56     mg_init(); /* initialize the parser */
57     /* get options & print header */
58     printf("## %s", argv[0]);
59     for (i = 1; i < argc && argv[i][0] == '-'; i++) {
60     printf(" %s", argv[i]);
61     switch (argv[i][1]) {
62     case 'g': /* glow distance (meters) */
63     if (argv[i][2] || badarg(argc-i, argv+i, "f"))
64     goto userr;
65     glowdist = atof(argv[++i]);
66     printf(" %s", argv[i]);
67     break;
68     case 'e': /* emitter multiplier */
69     if (argv[i][2] || badarg(argc-i, argv+i, "f"))
70     goto userr;
71     emult = atof(argv[++i]);
72     printf(" %s", argv[i]);
73     break;
74     default:
75     goto userr;
76     }
77     }
78     putchar('\n');
79     if (i == argc) { /* convert stdin */
80     if ((rv = mg_load(NULL)) != MG_OK)
81     exit(1);
82     } else /* convert each file */
83     for ( ; i < argc; i++) {
84     printf("## %s %s ##############################\n",
85     argv[0], argv[i]);
86     if ((rv = mg_load(argv[i])) != MG_OK)
87     exit(1);
88     }
89     exit(0);
90     userr:
91     fprintf(stderr, "Usage: %s [-g dist][-m mult] [file.mgf] ..\n",
92     argv[0]);
93     exit(1);
94     }
95    
96    
97     int
98     r_comment(ac, av) /* repeat a comment verbatim */
99     register int ac;
100     register char **av;
101     {
102     fputs("\n#", stdout); /* use Radiance comment character */
103     while (--ac) {
104     putchar(' ');
105     fputs(*++av, stdout);
106     }
107     putchar('\n');
108     return(MG_OK);
109     }
110    
111    
112     int
113     r_cone(ac, av) /* put out a cone */
114     int ac;
115     char **av;
116     {
117     static int ncones;
118     char *mat;
119     double r1, r2;
120     C_VERTEX *cv1, *cv2;
121     FVECT p1, p2;
122     int inv;
123    
124     if (ac != 5)
125     return(MG_EARGC);
126     if (!isflt(av[2]) || !isflt(av[4]))
127     return(MG_ETYPE);
128     if ((cv1 = c_getvert(av[1])) == NULL ||
129     (cv2 = c_getvert(av[3])) == NULL)
130     return(MG_EUNDEF);
131     xf_xfmpoint(p1, cv1->p);
132     xf_xfmpoint(p2, cv2->p);
133     r1 = xf_scale(atof(av[2]));
134     r2 = xf_scale(atof(av[4]));
135     inv = r1 < 0.;
136     if (r1 == 0.) {
137     if (r2 == 0.)
138     return(MG_EILL);
139     inv = r2 < 0.;
140     } else if (r2 != 0. && inv ^ r2 < 0.)
141     return(MG_EILL);
142     if (inv) {
143     r1 = -r1;
144     r2 = -r2;
145     }
146     if ((mat = material()) == NULL)
147     return(MG_EBADMAT);
148     printf("\n%s %s %sc%d\n", mat, inv ? "cup" : "cone",
149     object(), ++ncones);
150     printf("0\n0\n8\n");
151     putv(p1);
152     putv(p2);
153     printf("%18.12g %18.12g\n", r1, r2);
154     return(MG_OK);
155     }
156    
157    
158     int
159     r_cyl(ac, av) /* put out a cylinder */
160     int ac;
161     char **av;
162     {
163     static int ncyls;
164     char *mat;
165     double rad;
166     C_VERTEX *cv1, *cv2;
167     FVECT p1, p2;
168     int inv;
169    
170     if (ac != 4)
171     return(MG_EARGC);
172     if (!isflt(av[2]))
173     return(MG_ETYPE);
174     if ((cv1 = c_getvert(av[1])) == NULL ||
175     (cv2 = c_getvert(av[3])) == NULL)
176     return(MG_EUNDEF);
177     xf_xfmpoint(p1, cv1->p);
178     xf_xfmpoint(p2, cv2->p);
179     rad = xf_scale(atof(av[2]));
180     if ((inv = rad < 0.))
181     rad = -rad;
182     if ((mat = material()) == NULL)
183     return(MG_EBADMAT);
184     printf("\n%s %s %scy%d\n", mat, inv ? "tube" : "cylinder",
185     object(), ++ncyls);
186     printf("0\n0\n7\n");
187     putv(p1);
188     putv(p2);
189     printf("%18.12g\n", rad);
190     return(MG_OK);
191     }
192    
193    
194     int
195     r_sph(ac, av) /* put out a sphere */
196     int ac;
197     char **av;
198     {
199     static int nsphs;
200     char *mat;
201     double rad;
202     C_VERTEX *cv;
203     FVECT cent;
204     int inv;
205    
206     if (ac != 3)
207     return(MG_EARGC);
208     if (!isflt(av[2]))
209     return(MG_ETYPE);
210     if ((cv = c_getvert(av[1])) == NULL)
211     return(MG_EUNDEF);
212     xf_xfmpoint(cent, cv->p);
213     rad = xf_scale(atof(av[2]));
214     if ((inv = rad < 0.))
215     rad = -rad;
216     if ((mat = material()) == NULL)
217     return(MG_EBADMAT);
218     printf("\n%s %s %ss%d\n", mat, inv ? "bubble" : "sphere",
219     object(), ++nsphs);
220     printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
221     cent[0], cent[1], cent[2], rad);
222     return(MG_OK);
223     }
224    
225    
226     int
227     r_ring(ac, av) /* put out a ring */
228     int ac;
229     char **av;
230     {
231     static int nrings;
232     char *mat;
233     double r1, r2;
234     C_VERTEX *cv;
235     FVECT cent, norm;
236    
237     if (ac != 4)
238     return(MG_EARGC);
239     if (!isflt(av[2]) || !isflt(av[3]))
240     return(MG_ETYPE);
241     if ((cv = c_getvert(av[1])) == NULL)
242     return(MG_EUNDEF);
243     if (is0vect(cv->n))
244     return(MG_EILL);
245     xf_xfmpoint(cent, cv->p);
246     xf_rotvect(norm, cv->n);
247     r1 = xf_scale(atof(av[2]));
248     r2 = xf_scale(atof(av[3]));
249     if (r1 < 0. | r2 <= r1)
250     return(MG_EILL);
251     if ((mat = material()) == NULL)
252     return(MG_EBADMAT);
253     printf("\n%s ring %sr%d\n", mat, object(), ++nrings);
254     printf("0\n0\n8\n");
255     putv(cent);
256     putv(norm);
257     printf("%18.12g %18.12g\n", r1, r2);
258     return(MG_OK);
259     }
260    
261    
262     int
263     r_face(ac, av) /* convert a face */
264     int ac;
265     char **av;
266     {
267     static int nfaces;
268     char *mat;
269     register int i;
270     register C_VERTEX *cv;
271     FVECT v;
272     int rv;
273    
274     if (ac < 4)
275     return(MG_EARGC);
276     if ((mat = material()) == NULL)
277     return(MG_EBADMAT);
278 greg 2.2 if (ac <= 5) { /* check for surface normals */
279 greg 2.1 for (i = 1; i < ac; i++) {
280     if ((cv = c_getvert(av[i])) == NULL)
281     return(MG_EUNDEF);
282     if (is0vect(cv->n))
283     break;
284     }
285     if (i == ac) { /* break into triangles */
286     do_tri(mat, av[1], av[2], av[3]);
287     if (ac == 5)
288     do_tri(mat, av[3], av[4], av[1]);
289     return(MG_OK);
290     }
291     }
292     printf("\n%s polygon %sf%d\n", mat, object(), ++nfaces);
293     printf("0\n0\n%d\n", 3*(ac-1));
294     for (i = 1; i < ac; i++) {
295     if ((cv = c_getvert(av[i])) == NULL)
296     return(MG_EUNDEF);
297     xf_xfmpoint(v, cv->p);
298     putv(v);
299     }
300     return(MG_OK);
301     }
302    
303    
304     r_ies(ac, av) /* convert an IES luminaire file */
305     int ac;
306     char **av;
307     {
308     int xa0 = 2;
309     char combuf[72];
310     char fname[48];
311     char *oname;
312     register char *op;
313     register int i;
314    
315     if (ac < 2)
316     return(MG_EARGC);
317     (void)strcpy(combuf, "ies2rad");
318     op = combuf + 7;
319     if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
320     if (!isflt(av[xa0+1]))
321     return(MG_ETYPE);
322     op = addarg(addarg(op, "-m"), av[xa0+1]);
323     xa0 += 2;
324     }
325     if (access(av[1], 0) == -1)
326     return(MG_ENOFILE);
327     *op++ = ' '; /* IES filename goes last */
328     (void)strcpy(op, av[1]);
329     system(combuf); /* run ies2rad */
330     /* now let's find the output file */
331     if ((op = strrchr(av[1], '/')) == NULL)
332     op = av[1];
333     (void)strcpy(fname, op);
334     if ((op = strrchr(fname, '.')) == NULL)
335     op = fname + strlen(fname);
336     (void)strcpy(op, ".rad");
337     if (access(fname, 0) == -1)
338     return(MG_EINCL);
339     /* put out xform command */
340     printf("\n!xform");
341     oname = object();
342 greg 2.4 if (*oname) {
343     printf(" -n ");
344     for (op = oname; op[1]; op++) /* remove trailing separator */
345     putchar(*op);
346     }
347 greg 2.1 for (i = xa0; i < ac; i++)
348     printf(" %s", av[i]);
349     if (ac > xa0 && xf_argc > 0)
350     printf(" -i 1");
351     for (i = 0; i < xf_argc; i++)
352     printf(" %s", xf_argv[i]);
353     printf(" %s\n", fname);
354     return(MG_OK);
355     }
356    
357    
358     do_tri(mat, vn1, vn2, vn3) /* put out smoothed triangle */
359     char *mat, *vn1, *vn2, *vn3;
360     {
361     static int ntris;
362     BARYCCM bvecs;
363     FLOAT bcoor[3][3];
364     C_VERTEX *cv1, *cv2, *cv3;
365     FVECT v1, v2, v3;
366     FVECT n1, n2, n3;
367     register int i;
368     /* the following is repeat code, so assume it's OK */
369     cv1 = c_getvert(vn1);
370     cv2 = c_getvert(vn2);
371     cv3 = c_getvert(vn3);
372     xf_xfmpoint(v1, cv1->p);
373     xf_xfmpoint(v2, cv2->p);
374     xf_xfmpoint(v3, cv3->p);
375 greg 2.2 if (comp_baryc(&bvecs, v1, v2, v3) < 0)
376     return; /* degenerate triangle! */
377     printf("\n%s texfunc T-nor\n", mat);
378     printf("4 dx dy dz %s\n0\n", TCALNAME);
379     xf_rotvect(n1, cv1->n);
380     xf_rotvect(n2, cv2->n);
381     xf_rotvect(n3, cv3->n);
382     for (i = 0; i < 3; i++) {
383     bcoor[i][0] = n1[i];
384     bcoor[i][1] = n2[i];
385     bcoor[i][2] = n3[i];
386 greg 2.1 }
387 greg 2.2 put_baryc(&bvecs, bcoor, 3);
388     printf("\nT-nor polygon %st%d\n", object(), ++ntris);
389 greg 2.1 printf("0\n0\n9\n");
390     putv(v1);
391     putv(v2);
392     putv(v3);
393     }
394    
395    
396     char *
397     material() /* get (and print) current material */
398     {
399     char *mname = "mat";
400     COLOR radrgb, c2;
401     double d;
402     register int i;
403    
404 greg 2.5 if (c_cmname != NULL)
405     mname = c_cmname;
406 greg 2.1 if (!c_cmaterial->clock)
407     return(mname); /* already current */
408     /* else update output */
409     c_cmaterial->clock = 0;
410     if (c_cmaterial->ed > .1) { /* emitter */
411     cvtcolor(radrgb, &c_cmaterial->ed_c,
412     emult*c_cmaterial->ed/WHTEFFICACY);
413 greg 2.2 if (glowdist < FHUGE) { /* do a glow */
414 greg 2.1 printf("\nvoid glow %s\n0\n0\n", mname);
415     printf("4 %f %f %f %f\n", colval(radrgb,RED),
416     colval(radrgb,GRN),
417     colval(radrgb,BLU), glowdist);
418     } else {
419     printf("\nvoid light %s\n0\n0\n", mname);
420     printf("3 %f %f %f\n", colval(radrgb,RED),
421     colval(radrgb,GRN),
422     colval(radrgb,BLU));
423     }
424     return(mname);
425     }
426     d = c_cmaterial->rd + c_cmaterial->td +
427     c_cmaterial->rs + c_cmaterial->ts;
428     if (d <= 0. | d >= 1.)
429     return(NULL);
430 greg 2.3 /* check for trans */
431     if (c_cmaterial->td > .01 || c_cmaterial->ts > .01) {
432 greg 2.1 double ts, a5, a6;
433    
434     ts = sqrt(c_cmaterial->ts); /* because we use 2 sides */
435     /* average colors */
436     d = c_cmaterial->rd + c_cmaterial->td + ts;
437     cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd/d);
438     cvtcolor(c2, &c_cmaterial->td_c, c_cmaterial->td/d);
439     addcolor(radrgb, c2);
440     cvtcolor(c2, &c_cmaterial->ts_c, ts/d);
441     addcolor(radrgb, c2);
442     if (c_cmaterial->rs + ts > .0001)
443     a5 = (c_cmaterial->rs*c_cmaterial->rs_a +
444     ts*.5*c_cmaterial->ts_a) /
445     (c_cmaterial->rs + ts);
446     a6 = (c_cmaterial->td + ts) /
447     (c_cmaterial->rd + c_cmaterial->td + ts);
448     if (a6 < .999) {
449     d = c_cmaterial->rd/(1. - c_cmaterial->rs)/(1. - a6);
450     scalecolor(radrgb, d);
451     }
452     printf("\nvoid trans %s\n0\n0\n", mname);
453     printf("7 %f %f %f\n", colval(radrgb,RED),
454     colval(radrgb,GRN), colval(radrgb,BLU));
455     printf("\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
456     ts/(ts + c_cmaterial->td));
457     return(mname);
458     }
459 greg 2.3 /* check for plastic */
460     if (c_cmaterial->rs < .01 || c_isgrey(&c_cmaterial->rs_c)) {
461 greg 2.1 if (c_cmaterial->rs > .999)
462     cvtcolor(radrgb, &c_cmaterial->rd_c, 1.);
463     else
464     cvtcolor(radrgb, &c_cmaterial->rd_c,
465     c_cmaterial->rd/(1.-c_cmaterial->rs));
466     printf("\nvoid plastic %s\n0\n0\n", mname);
467     printf("5 %f %f %f %f %f\n", colval(radrgb,RED),
468     colval(radrgb,GRN), colval(radrgb,BLU),
469     c_cmaterial->rs, c_cmaterial->rs_a);
470     return(mname);
471     }
472     /* else it's metal */
473     d = c_cmaterial->rd + c_cmaterial->rs; /* average colors */
474     cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd/d);
475     cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs/d);
476     addcolor(radrgb, c2);
477     if (c_cmaterial->rs < .999) {
478     d = c_cmaterial->rd/(1. - c_cmaterial->rs);
479     scalecolor(radrgb, d);
480     }
481     printf("\nvoid metal %s\n0\n0\n", mname);
482     printf("5 %f %f %f %f %f\n", colval(radrgb,RED),
483     colval(radrgb,GRN), colval(radrgb,BLU),
484     c_cmaterial->rs, c_cmaterial->rs_a);
485     return(mname);
486     }
487    
488    
489     cvtcolor(radrgb, ciec, intensity) /* convert a CIE color to Radiance */
490     COLOR radrgb;
491     register C_COLOR *ciec;
492     double intensity;
493     {
494     static COLOR ciexyz;
495    
496 greg 2.4 c_ccvt(ciec, C_CSXY); /* get xy representation */
497 greg 2.1 ciexyz[1] = intensity;
498     ciexyz[0] = ciec->cx/ciec->cy*ciexyz[1];
499     ciexyz[2] = ciexyz[1]*(1./ciec->cy - 1.) - ciexyz[0];
500     cie_rgb(radrgb, ciexyz);
501     }
502    
503    
504     char *
505     object() /* return current object name */
506     {
507     static char objbuf[64];
508     register int i;
509     register char *cp;
510     int len;
511    
512     i = obj_nnames - sizeof(objbuf)/16;
513     if (i < 0)
514     i = 0;
515     for (cp = objbuf; i < obj_nnames &&
516     cp + (len=strlen(obj_name[i])) < objbuf+sizeof(objbuf)-1;
517     i++, *cp++ = '.') {
518     strcpy(cp, obj_name[i]);
519     cp += len;
520     }
521     *cp = '\0';
522     return(objbuf);
523     }
524    
525    
526     char *
527     addarg(op, arg) /* add argument and advance pointer */
528     register char *op, *arg;
529     {
530     *op = ' ';
531     while (*++op = *arg++)
532     ;
533     return(op);
534     }