ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.37
Committed: Mon Aug 15 19:48:06 2011 UTC (12 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.36: +1 -2 lines
Log Message:
Made direct visibility (-dv) flag irrelevant and fixed BSDF material sampling

File Contents

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