ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.33
Committed: Thu Dec 13 07:03:37 2007 UTC (16 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R9
Changes since 2.32: +3 -3 lines
Log Message:
Superficially working version of mkillum with BSDF input

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: mkillum.c,v 2.32 2007/12/08 01:43:09 greg Exp $";
3 #endif
4 /*
5 * Make illum sources for optimizing rendering process
6 */
7
8 #include <signal.h>
9 #include <ctype.h>
10
11 #include "mkillum.h"
12
13 /* default parameters */
14 #define SAMPDENS 48 /* points per projected steradian */
15 #define NSAMPS 32 /* samples per point */
16 #define DFLMAT "illum_mat" /* material name */
17 #define DFLDAT "illum" /* data file name */
18 /* selection options */
19 #define S_NONE 0 /* select none */
20 #define S_ELEM 1 /* select specified element */
21 #define S_COMPL 2 /* select all but element */
22 #define S_ALL 3 /* select all */
23
24 struct illum_args thisillum = { /* our illum and default values */
25 0,
26 UDzpos,
27 0.,
28 DFLMAT,
29 DFLDAT,
30 0,
31 VOIDID,
32 SAMPDENS,
33 NSAMPS,
34 NULL,
35 0.,
36 };
37
38 char matcheck[MAXSTR]; /* current material to include or exclude */
39 int matselect = S_ALL; /* selection criterion */
40
41 int gargc; /* global argc */
42 char **gargv; /* global argv */
43
44 int doneheader = 0; /* printed header yet? */
45 #define checkhead() if (!doneheader++) printhead(gargc,gargv)
46
47 int warnings = 1; /* print warnings? */
48
49 void init(char *octnm, int np);
50 void filter(register FILE *infp, char *name);
51 void xoptions(char *s, char *nm);
52 void printopts(void);
53 void printhead(register int ac, register char **av);
54 void xobject(FILE *fp, char *nm);
55
56
57 int
58 main( /* compute illum distributions using rtrace */
59 int argc,
60 char *argv[]
61 )
62 {
63 int nprocs = 1;
64 FILE *fp;
65 int rval;
66 register int i;
67 /* set global arguments */
68 gargv = argv;
69 progname = gargv[0];
70 /* set up rendering defaults */
71 dstrsrc = 0.25;
72 directrelay = 3;
73 directvis = 0;
74 ambounce = 2;
75 /* get options from command line */
76 for (i = 1; i < argc; i++) {
77 while ((rval = expandarg(&argc, &argv, i)) > 0)
78 ;
79 if (rval < 0) {
80 sprintf(errmsg, "cannot expand '%s'", argv[i]);
81 error(SYSTEM, errmsg);
82 }
83 if (argv[i][0] != '-')
84 break;
85 if (!strcmp(argv[i], "-w")) {
86 warnings = 0;
87 continue;
88 }
89 if (!strcmp(argv[i], "-n")) {
90 nprocs = atoi(argv[++i]);
91 if (nprocs <= 0)
92 error(USER, "illegal number of processes");
93 continue;
94 }
95 if (!strcmp(argv[i], "-defaults")) {
96 printopts();
97 print_rdefaults();
98 quit(0);
99 }
100 rval = getrenderopt(argc-i, argv+i);
101 if (rval < 0) {
102 sprintf(errmsg, "bad render option at '%s'", argv[i]);
103 error(USER, errmsg);
104 }
105 i += rval;
106 }
107 gargc = ++i;
108 /* add "mandatory" render options */
109 do_irrad = 0;
110 if (gargc > argc || argv[gargc-1][0] == '-')
111 error(USER, "missing octree argument");
112 /* else initialize and run our calculation */
113 init(argv[gargc-1], nprocs);
114 if (gargc < argc) {
115 if (gargc == argc-1 || argv[gargc][0] != '<' || argv[gargc][1])
116 error(USER, "use '< file1 file2 ..' for multiple inputs");
117 for (i = gargc+1; i < argc; i++) {
118 if ((fp = fopen(argv[i], "r")) == NULL) {
119 sprintf(errmsg,
120 "cannot open scene file \"%s\"", argv[i]);
121 error(SYSTEM, errmsg);
122 }
123 filter(fp, argv[i]);
124 fclose(fp);
125 }
126 } else
127 filter(stdin, "standard input");
128 quit(0);
129 return 0; /* pro forma return */
130 }
131
132
133 void
134 init(char *octnm, int np) /* start rendering process(es) */
135 {
136 /* set up signal handling */
137 signal(SIGINT, quit);
138 #ifdef SIGHUP
139 signal(SIGHUP, quit);
140 #endif
141 #ifdef SIGTERM
142 signal(SIGTERM, quit);
143 #endif
144 #ifdef SIGPIPE
145 signal(SIGPIPE, quit);
146 #endif
147 /* start rendering process(es) */
148 ray_pinit(octnm, np);
149 }
150
151
152 void
153 eputs( /* put string to stderr */
154 register char *s
155 )
156 {
157 static int midline = 0;
158
159 if (!*s) return;
160 if (!midline) {
161 fputs(progname, stderr);
162 fputs(": ", stderr);
163 }
164 fputs(s, stderr);
165 midline = s[strlen(s)-1] != '\n';
166 }
167
168
169 void
170 wputs(s) /* print warning if enabled */
171 char *s;
172 {
173 if (warnings)
174 eputs(s);
175 }
176
177
178 void
179 filter( /* process stream */
180 register FILE *infp,
181 char *name
182 )
183 {
184 char buf[512];
185 FILE *pfp;
186 register int c;
187
188 while ((c = getc(infp)) != EOF) {
189 if (isspace(c))
190 continue;
191 if (c == '#') { /* comment/options */
192 buf[0] = c;
193 fgets(buf+1, sizeof(buf)-1, infp);
194 xoptions(buf, name);
195 } else if (c == '!') { /* command */
196 buf[0] = c;
197 fgetline(buf+1, sizeof(buf)-1, infp);
198 if ((pfp = popen(buf+1, "r")) == NULL) {
199 sprintf(errmsg, "cannot execute \"%s\"", buf);
200 error(SYSTEM, errmsg);
201 }
202 filter(pfp, buf);
203 pclose(pfp);
204 } else { /* object */
205 ungetc(c, infp);
206 xobject(infp, name);
207 }
208 }
209 }
210
211
212 void
213 xoptions( /* process options in string s */
214 char *s,
215 char *nm
216 )
217 {
218 extern FILE *freopen();
219 char buf[64];
220 int negax;
221 int nerrs = 0;
222 register char *cp;
223
224 if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
225 fputs(s, stdout); /* not for us */
226 return;
227 }
228 cp = s+10;
229 while (*cp) {
230 switch (*cp) {
231 case ' ':
232 case '\t':
233 case '\n':
234 case '\r':
235 case '\f':
236 cp++;
237 continue;
238 case 'm': /* material name */
239 if (*++cp != '=')
240 break;
241 if (!*++cp || isspace(*cp))
242 break;
243 atos(thisillum.matname, MAXSTR, cp);
244 cp = sskip(cp);
245 if (!(thisillum.flags & IL_DATCLB)) {
246 strcpy(thisillum.datafile, thisillum.matname);
247 thisillum.dfnum = 0;
248 }
249 continue;
250 case 'f': /* data file name */
251 if (*++cp != '=')
252 break;
253 if (!*++cp || isspace(*cp)) {
254 strcpy(thisillum.datafile,thisillum.matname);
255 thisillum.dfnum = 0;
256 thisillum.flags &= ~IL_DATCLB;
257 continue;
258 }
259 atos(thisillum.datafile, MAXSTR, cp);
260 cp = sskip(cp);
261 thisillum.dfnum = 0;
262 thisillum.flags |= IL_DATCLB;
263 continue;
264 case 'i': /* include material */
265 case 'e': /* exclude material */
266 if (cp[1] != '=')
267 break;
268 matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
269 cp += 2;
270 atos(matcheck, MAXSTR, cp);
271 cp = sskip(cp);
272 continue;
273 case 'a': /* use everything */
274 cp = sskip(cp);
275 matselect = S_ALL;
276 continue;
277 case 'n': /* use nothing (passive) */
278 cp = sskip(cp);
279 matselect = S_NONE;
280 continue;
281 case 'c': /* color calculation */
282 if (*++cp != '=')
283 break;
284 switch (*++cp) {
285 case 'a': /* average */
286 thisillum.flags = (thisillum.flags|IL_COLAVG)
287 & ~IL_COLDST;
288 break;
289 case 'd': /* distribution */
290 thisillum.flags |= (IL_COLDST|IL_COLAVG);
291 break;
292 case 'n': /* none */
293 thisillum.flags &= ~(IL_COLAVG|IL_COLDST);
294 break;
295 default:
296 goto opterr;
297 }
298 cp = sskip(cp);
299 continue;
300 case 'd': /* sample density / BSDF data */
301 if (*++cp != '=')
302 break;
303 if (thisillum.sd != NULL) {
304 free_BSDF(thisillum.sd);
305 thisillum.sd = NULL;
306 }
307 if (!*++cp || isspace(*cp))
308 continue;
309 if (isintd(cp, " \t\n\r")) {
310 thisillum.sampdens = atoi(cp);
311 } else {
312 atos(buf, sizeof(buf), cp);
313 thisillum.sd = load_BSDF(buf);
314 if (thisillum.sd == NULL)
315 break;
316 }
317 cp = sskip(cp);
318 continue;
319 case 's': /* surface super-samples */
320 if (*++cp != '=')
321 break;
322 if (!isintd(++cp, " \t\n\r"))
323 break;
324 thisillum.nsamps = atoi(cp);
325 cp = sskip(cp);
326 continue;
327 case 'l': /* light sources */
328 cp++;
329 if (*cp == '+')
330 thisillum.flags |= IL_LIGHT;
331 else if (*cp == '-')
332 thisillum.flags &= ~IL_LIGHT;
333 else
334 break;
335 cp++;
336 continue;
337 case 'b': /* brightness */
338 if (*++cp != '=')
339 break;
340 if (!isfltd(++cp, " \t\n\r"))
341 break;
342 thisillum.minbrt = atof(cp);
343 if (thisillum.minbrt < 0.)
344 thisillum.minbrt = 0.;
345 cp = sskip(cp);
346 continue;
347 case 'o': /* output file */
348 if (*++cp != '=')
349 break;
350 if (!*++cp || isspace(*cp))
351 break;
352 atos(buf, sizeof(buf), cp);
353 cp = sskip(cp);
354 if (freopen(buf, "w", stdout) == NULL) {
355 sprintf(errmsg,
356 "cannot open output file \"%s\"", buf);
357 error(SYSTEM, errmsg);
358 }
359 doneheader = 0;
360 continue;
361 case 'u': /* up direction */
362 if (*++cp != '=')
363 break;
364 if (!*++cp || isspace(*cp)) {
365 thisillum.udir = UDunknown;
366 continue;
367 }
368 negax = 0;
369 if (*cp == '+')
370 cp++;
371 else if (*cp == '-') {
372 negax++;
373 cp++;
374 }
375 switch (*cp++) {
376 case 'x':
377 case 'X':
378 thisillum.udir = negax ? UDxneg : UDxpos;
379 break;
380 case 'y':
381 case 'Y':
382 thisillum.udir = negax ? UDyneg : UDypos;
383 break;
384 case 'z':
385 case 'Z':
386 thisillum.udir = negax ? UDzneg : UDzpos;
387 break;
388 default:
389 thisillum.udir = UDunknown;
390 break;
391 }
392 if (thisillum.udir == UDunknown || !isspace(*cp))
393 break;
394 continue;
395 case 't': /* object thickness */
396 if (*++cp != '=')
397 break;
398 if (!isfltd(++cp, " \t\n\r"))
399 break;
400 thisillum.thick = atof(cp);
401 if (thisillum.thick < .0)
402 thisillum.thick = .0;
403 cp = sskip(cp);
404 continue;
405 case '!': /* processed file! */
406 sprintf(errmsg, "(%s): already processed!", nm);
407 error(WARNING, errmsg);
408 matselect = S_NONE;
409 return;
410 }
411 opterr: /* skip faulty option */
412 while (*cp && !isspace(*cp))
413 cp++;
414 nerrs++;
415 }
416 /* print header? */
417 checkhead();
418 /* issue warnings? */
419 if (nerrs) {
420 sprintf(errmsg, "(%s): %d error(s) in option line:",
421 nm, nerrs);
422 error(WARNING, errmsg);
423 wputs(s);
424 printf("# %s: the following option line has %d error(s):\n",
425 progname, nerrs);
426 }
427 /* print pure comment */
428 printf("# %s", s+2);
429 }
430
431 void
432 printopts(void) /* print out option default values */
433 {
434 printf("m=%-15s\t\t# material name\n", thisillum.matname);
435 printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
436 if (thisillum.flags & IL_COLAVG)
437 if (thisillum.flags & IL_COLDST)
438 printf("c=d\t\t\t\t# color distribution\n");
439 else
440 printf("c=a\t\t\t\t# color average\n");
441 else
442 printf("c=n\t\t\t\t# color none\n");
443 if (thisillum.flags & IL_LIGHT)
444 printf("l+\t\t\t\t# light type on\n");
445 else
446 printf("l-\t\t\t\t# light type off\n");
447 printf("d=%d\t\t\t\t# density of points\n", thisillum.sampdens);
448 printf("s=%d\t\t\t\t# samples per point\n", thisillum.nsamps);
449 printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
450 switch (thisillum.udir) {
451 case UDzneg:
452 fputs("u=-Z\t\t\t\t# up is negative Z\n", stdout);
453 break;
454 case UDyneg:
455 fputs("u=-Y\t\t\t\t# up is negative Y\n", stdout);
456 break;
457 case UDxneg:
458 fputs("u=-X\t\t\t\t# up is negative X\n", stdout);
459 break;
460 case UDxpos:
461 fputs("u=+X\t\t\t\t# up is positive X\n", stdout);
462 break;
463 case UDypos:
464 fputs("u=+Y\t\t\t\t# up is positive Y\n", stdout);
465 break;
466 case UDzpos:
467 fputs("u=+Z\t\t\t\t# up is positive Z\n", stdout);
468 break;
469 case UDunknown:
470 break;
471 }
472 printf("t=%f\t\t\t# object thickness\n", thisillum.thick);
473 }
474
475
476 void
477 printhead( /* print out header */
478 register int ac,
479 register char **av
480 )
481 {
482 putchar('#');
483 while (ac-- > 0) {
484 putchar(' ');
485 fputs(*av++, stdout);
486 }
487 fputs("\n#@mkillum !\n", stdout);
488 }
489
490
491 void
492 xobject( /* translate an object from fp */
493 FILE *fp,
494 char *nm
495 )
496 {
497 OBJREC thisobj;
498 char str[MAXSTR];
499 int doit;
500 /* read the object */
501 if (fgetword(thisillum.altmat, MAXSTR, fp) == NULL)
502 goto readerr;
503 if (fgetword(str, MAXSTR, fp) == NULL)
504 goto readerr;
505 /* is it an alias? */
506 if (!strcmp(str, ALIASKEY)) {
507 if (fgetword(str, MAXSTR, fp) == NULL)
508 goto readerr;
509 printf("\n%s %s %s", thisillum.altmat, ALIASKEY, str);
510 if (fgetword(str, MAXSTR, fp) == NULL)
511 goto readerr;
512 printf("\t%s\n", str);
513 return;
514 }
515 thisobj.omod = OVOID; /* unused field */
516 if ((thisobj.otype = otype(str)) < 0) {
517 sprintf(errmsg, "(%s): unknown type \"%s\"", nm, str);
518 error(USER, errmsg);
519 }
520 if (fgetword(str, MAXSTR, fp) == NULL)
521 goto readerr;
522 thisobj.oname = str;
523 if (readfargs(&thisobj.oargs, fp) != 1)
524 goto readerr;
525 thisobj.os = NULL;
526 /* check for translation */
527 switch (matselect) {
528 case S_NONE:
529 doit = 0;
530 break;
531 case S_ALL:
532 doit = 1;
533 break;
534 case S_ELEM:
535 doit = !strcmp(thisillum.altmat, matcheck);
536 break;
537 case S_COMPL:
538 doit = strcmp(thisillum.altmat, matcheck);
539 break;
540 }
541 doit = doit && issurface(thisobj.otype);
542 /* print header? */
543 checkhead();
544 /* process object */
545 if (doit)
546 switch (thisobj.otype) {
547 case OBJ_FACE:
548 my_face(&thisobj, &thisillum, nm);
549 break;
550 case OBJ_SPHERE:
551 my_sphere(&thisobj, &thisillum, nm);
552 break;
553 case OBJ_RING:
554 my_ring(&thisobj, &thisillum, nm);
555 break;
556 default:
557 my_default(&thisobj, &thisillum, nm);
558 break;
559 }
560 else
561 printobj(thisillum.altmat, &thisobj);
562 /* free arguments */
563 freefargs(&thisobj.oargs);
564 return;
565 readerr:
566 sprintf(errmsg, "(%s): error reading input", nm);
567 error(USER, errmsg);
568 }