ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.36
Committed: Sat Dec 12 19:00:59 2009 UTC (14 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R0
Changes since 2.35: +11 -1 lines
Log Message:
Added -n option to rtrace and moved quit() funciton out of raypcalls

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: mkillum.c,v 2.35 2009/06/06 05:03:47 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 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 quit(ec) /* make sure exit is called */
180 int ec;
181 {
182 if (ray_pnprocs > 0) /* close children if any */
183 ray_pclose(0);
184 exit(ec);
185 }
186
187
188 void
189 filter( /* process stream */
190 register FILE *infp,
191 char *name
192 )
193 {
194 char buf[512];
195 FILE *pfp;
196 register int c;
197
198 while ((c = getc(infp)) != EOF) {
199 if (isspace(c))
200 continue;
201 if (c == '#') { /* comment/options */
202 buf[0] = c;
203 fgets(buf+1, sizeof(buf)-1, infp);
204 xoptions(buf, name);
205 } else if (c == '!') { /* command */
206 buf[0] = c;
207 fgetline(buf+1, sizeof(buf)-1, infp);
208 if ((pfp = popen(buf+1, "r")) == NULL) {
209 sprintf(errmsg, "cannot execute \"%s\"", buf);
210 error(SYSTEM, errmsg);
211 }
212 filter(pfp, buf);
213 pclose(pfp);
214 } else { /* object */
215 ungetc(c, infp);
216 xobject(infp, name);
217 }
218 }
219 }
220
221
222 void
223 xoptions( /* process options in string s */
224 char *s,
225 char *nm
226 )
227 {
228 extern FILE *freopen();
229 char buf[64];
230 int negax;
231 int nerrs = 0;
232 register char *cp;
233
234 if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
235 fputs(s, stdout); /* not for us */
236 return;
237 }
238 cp = s+10;
239 while (*cp) {
240 switch (*cp) {
241 case ' ':
242 case '\t':
243 case '\n':
244 case '\r':
245 case '\f':
246 cp++;
247 continue;
248 case 'm': /* material name */
249 if (*++cp != '=')
250 break;
251 if (!*++cp || isspace(*cp))
252 break;
253 atos(thisillum.matname, MAXSTR, cp);
254 cp = sskip(cp);
255 if (!(thisillum.flags & IL_DATCLB)) {
256 strcpy(thisillum.datafile, thisillum.matname);
257 thisillum.dfnum = 0;
258 }
259 continue;
260 case 'f': /* data file name */
261 if (*++cp != '=')
262 break;
263 if (!*++cp || isspace(*cp)) {
264 strcpy(thisillum.datafile,thisillum.matname);
265 thisillum.dfnum = 0;
266 thisillum.flags &= ~IL_DATCLB;
267 continue;
268 }
269 atos(thisillum.datafile, MAXSTR, cp);
270 cp = sskip(cp);
271 thisillum.dfnum = 0;
272 thisillum.flags |= IL_DATCLB;
273 continue;
274 case 'i': /* include material */
275 case 'e': /* exclude material */
276 if (cp[1] != '=')
277 break;
278 matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
279 cp += 2;
280 atos(matcheck, MAXSTR, cp);
281 cp = sskip(cp);
282 continue;
283 case 'a': /* use everything */
284 cp = sskip(cp);
285 matselect = S_ALL;
286 continue;
287 case 'n': /* use nothing (passive) */
288 cp = sskip(cp);
289 matselect = S_NONE;
290 continue;
291 case 'c': /* color calculation */
292 if (*++cp != '=')
293 break;
294 switch (*++cp) {
295 case 'a': /* average */
296 thisillum.flags = (thisillum.flags|IL_COLAVG)
297 & ~IL_COLDST;
298 break;
299 case 'd': /* distribution */
300 thisillum.flags |= (IL_COLDST|IL_COLAVG);
301 break;
302 case 'n': /* none */
303 thisillum.flags &= ~(IL_COLAVG|IL_COLDST);
304 break;
305 default:
306 goto opterr;
307 }
308 cp = sskip(cp);
309 continue;
310 case 'd': /* sample density / BSDF data */
311 if (*++cp != '=')
312 break;
313 if (thisillum.sd != NULL) {
314 free_BSDF(thisillum.sd);
315 thisillum.sd = NULL;
316 }
317 if (!*++cp || isspace(*cp))
318 continue;
319 if (isintd(cp, " \t\n\r")) {
320 thisillum.sampdens = atoi(cp);
321 } else {
322 atos(buf, sizeof(buf), cp);
323 thisillum.sd = load_BSDF(buf);
324 if (thisillum.sd == NULL)
325 break;
326 }
327 cp = sskip(cp);
328 continue;
329 case 's': /* surface super-samples */
330 if (*++cp != '=')
331 break;
332 if (!isintd(++cp, " \t\n\r"))
333 break;
334 thisillum.nsamps = atoi(cp);
335 cp = sskip(cp);
336 continue;
337 case 'l': /* light sources */
338 cp++;
339 if (*cp == '+')
340 thisillum.flags |= IL_LIGHT;
341 else if (*cp == '-')
342 thisillum.flags &= ~IL_LIGHT;
343 else
344 break;
345 cp++;
346 continue;
347 case 'b': /* brightness */
348 if (*++cp != '=')
349 break;
350 if (!isfltd(++cp, " \t\n\r"))
351 break;
352 thisillum.minbrt = atof(cp);
353 if (thisillum.minbrt < 0.)
354 thisillum.minbrt = 0.;
355 cp = sskip(cp);
356 continue;
357 case 'o': /* output file */
358 if (*++cp != '=')
359 break;
360 if (!*++cp || isspace(*cp))
361 break;
362 atos(buf, sizeof(buf), cp);
363 cp = sskip(cp);
364 if (freopen(buf, "w", stdout) == NULL) {
365 sprintf(errmsg,
366 "cannot open output file \"%s\"", buf);
367 error(SYSTEM, errmsg);
368 }
369 doneheader = 0;
370 continue;
371 case 'u': /* up direction */
372 if (*++cp != '=')
373 break;
374 if (!*++cp || isspace(*cp)) {
375 thisillum.udir = UDunknown;
376 continue;
377 }
378 negax = 0;
379 if (*cp == '+')
380 cp++;
381 else if (*cp == '-') {
382 negax++;
383 cp++;
384 }
385 switch (*cp++) {
386 case 'x':
387 case 'X':
388 thisillum.udir = negax ? UDxneg : UDxpos;
389 break;
390 case 'y':
391 case 'Y':
392 thisillum.udir = negax ? UDyneg : UDypos;
393 break;
394 case 'z':
395 case 'Z':
396 thisillum.udir = negax ? UDzneg : UDzpos;
397 break;
398 default:
399 thisillum.udir = UDunknown;
400 break;
401 }
402 if (thisillum.udir == UDunknown || !isspace(*cp))
403 break;
404 continue;
405 case 't': /* object thickness */
406 if (*++cp != '=')
407 break;
408 if (!isfltd(++cp, " \t\n\r"))
409 break;
410 thisillum.thick = atof(cp);
411 if (thisillum.thick < .0)
412 thisillum.thick = .0;
413 cp = sskip(cp);
414 continue;
415 case '!': /* processed file! */
416 sprintf(errmsg, "(%s): already processed!", nm);
417 error(WARNING, errmsg);
418 matselect = S_NONE;
419 return;
420 }
421 opterr: /* skip faulty option */
422 while (*cp && !isspace(*cp))
423 cp++;
424 nerrs++;
425 }
426 /* print header? */
427 checkhead();
428 /* issue warnings? */
429 if (nerrs) {
430 sprintf(errmsg, "(%s): %d error(s) in option line:",
431 nm, nerrs);
432 error(WARNING, errmsg);
433 wputs(s);
434 printf("# %s: the following option line has %d error(s):\n",
435 progname, nerrs);
436 }
437 /* print pure comment */
438 printf("# %s", s+2);
439 }
440
441 void
442 printopts(void) /* print out option default values */
443 {
444 printf("m=%-15s\t\t# material name\n", thisillum.matname);
445 printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
446 if (thisillum.flags & IL_COLAVG)
447 if (thisillum.flags & IL_COLDST)
448 printf("c=d\t\t\t\t# color distribution\n");
449 else
450 printf("c=a\t\t\t\t# color average\n");
451 else
452 printf("c=n\t\t\t\t# color none\n");
453 if (thisillum.flags & IL_LIGHT)
454 printf("l+\t\t\t\t# light type on\n");
455 else
456 printf("l-\t\t\t\t# light type off\n");
457 printf("d=%d\t\t\t\t# density of directions\n", thisillum.sampdens);
458 printf("s=%d\t\t\t\t# samples per direction\n", thisillum.nsamps);
459 printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
460 switch (thisillum.udir) {
461 case UDzneg:
462 fputs("u=-Z\t\t\t\t# up is negative Z\n", stdout);
463 break;
464 case UDyneg:
465 fputs("u=-Y\t\t\t\t# up is negative Y\n", stdout);
466 break;
467 case UDxneg:
468 fputs("u=-X\t\t\t\t# up is negative X\n", stdout);
469 break;
470 case UDxpos:
471 fputs("u=+X\t\t\t\t# up is positive X\n", stdout);
472 break;
473 case UDypos:
474 fputs("u=+Y\t\t\t\t# up is positive Y\n", stdout);
475 break;
476 case UDzpos:
477 fputs("u=+Z\t\t\t\t# up is positive Z\n", stdout);
478 break;
479 case UDunknown:
480 break;
481 }
482 printf("t=%f\t\t\t# object thickness\n", thisillum.thick);
483 }
484
485
486 void
487 printhead( /* print out header */
488 register int ac,
489 register char **av
490 )
491 {
492 putchar('#');
493 while (ac-- > 0) {
494 putchar(' ');
495 fputs(*av++, stdout);
496 }
497 fputs("\n#@mkillum !\n", stdout);
498 }
499
500
501 void
502 xobject( /* translate an object from fp */
503 FILE *fp,
504 char *nm
505 )
506 {
507 OBJREC thisobj;
508 char str[MAXSTR];
509 int doit;
510 /* read the object */
511 if (fgetword(thisillum.altmat, MAXSTR, fp) == NULL)
512 goto readerr;
513 if (fgetword(str, MAXSTR, fp) == NULL)
514 goto readerr;
515 /* is it an alias? */
516 if (!strcmp(str, ALIASKEY)) {
517 if (fgetword(str, MAXSTR, fp) == NULL)
518 goto readerr;
519 printf("\n%s %s %s", thisillum.altmat, ALIASKEY, str);
520 if (fgetword(str, MAXSTR, fp) == NULL)
521 goto readerr;
522 printf("\t%s\n", str);
523 return;
524 }
525 thisobj.omod = OVOID; /* unused field */
526 if ((thisobj.otype = otype(str)) < 0) {
527 sprintf(errmsg, "(%s): unknown type \"%s\"", nm, str);
528 error(USER, errmsg);
529 }
530 if (fgetword(str, MAXSTR, fp) == NULL)
531 goto readerr;
532 thisobj.oname = str;
533 if (readfargs(&thisobj.oargs, fp) != 1)
534 goto readerr;
535 thisobj.os = NULL;
536 /* check for translation */
537 switch (matselect) {
538 case S_NONE:
539 doit = 0;
540 break;
541 case S_ALL:
542 doit = 1;
543 break;
544 case S_ELEM:
545 doit = !strcmp(thisillum.altmat, matcheck);
546 break;
547 case S_COMPL:
548 doit = strcmp(thisillum.altmat, matcheck);
549 break;
550 }
551 doit = doit && issurface(thisobj.otype);
552 /* print header? */
553 checkhead();
554 /* process object */
555 if (doit)
556 switch (thisobj.otype) {
557 case OBJ_FACE:
558 my_face(&thisobj, &thisillum, nm);
559 break;
560 case OBJ_SPHERE:
561 my_sphere(&thisobj, &thisillum, nm);
562 break;
563 case OBJ_RING:
564 my_ring(&thisobj, &thisillum, nm);
565 break;
566 default:
567 my_default(&thisobj, &thisillum, nm);
568 break;
569 }
570 else
571 printobj(thisillum.altmat, &thisobj);
572 /* free arguments */
573 freefargs(&thisobj.oargs);
574 return;
575 readerr:
576 sprintf(errmsg, "(%s): error reading input", nm);
577 error(USER, errmsg);
578 }