ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgf2rad.c
Revision: 2.13
Committed: Tue Mar 7 12:18:15 1995 UTC (29 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.12: +1 -0 lines
Log Message:
added cct entity

File Contents

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