ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.22
Committed: Sat Oct 23 18:55:52 2004 UTC (19 years, 5 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.21: +2 -1 lines
Log Message:
Compatibility fixes as suggested by Siegbert Debatin.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: mkillum.c,v 2.21 2004/09/19 08:42:22 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 "platform.h"
12 #include "rtprocess.h"
13 #include "mkillum.h"
14 #include "random.h"
15
16 /* default parameters */
17 #define SAMPDENS 48 /* points per projected steradian */
18 #define NSAMPS 32 /* samples per point */
19 #define DFLMAT "illum_mat" /* material name */
20 #define DFLDAT "illum" /* data file name */
21 /* selection options */
22 #define S_NONE 0 /* select none */
23 #define S_ELEM 1 /* select specified element */
24 #define S_COMPL 2 /* select all but element */
25 #define S_ALL 3 /* select all */
26
27 /* rtrace command and defaults */
28 char *rtargv[64] = { "rtrace", "-dj", ".25", "-dr", "3", "-dv-",
29 "-ab", "2", "-ad", "1024", "-as", "512", "-aa", ".1", };
30 int rtargc = 14;
31 /* overriding rtrace options */
32 char *myrtopts[] = { "-I-", "-i-", "-ld-", "-ov", "-h-",
33 "-fff", "-y", "0", NULL };
34
35 struct rtproc rt0; /* head of rtrace process list */
36
37 struct illum_args thisillum = { /* our illum and default values */
38 0,
39 DFLMAT,
40 DFLDAT,
41 0,
42 VOIDID,
43 SAMPDENS,
44 NSAMPS,
45 0.,
46 };
47
48 char matcheck[MAXSTR]; /* current material to include or exclude */
49 int matselect = S_ALL; /* selection criterion */
50
51 FUN ofun[NUMOTYPE] = INIT_OTYPE; /* object types */
52
53 char persistfn[] = "pfXXXXXX"; /* persist file name */
54
55 int gargc; /* global argc */
56 char **gargv; /* global argv */
57 #define progname gargv[0]
58
59 int doneheader = 0; /* printed header yet? */
60 #define checkhead() if (!doneheader++) printhead(gargc,gargv)
61
62 int warnings = 1; /* print warnings? */
63
64 void init(int np);
65 void filter(register FILE *infp, char *name);
66 void xoptions(char *s, char *nm);
67 void printopts(void);
68 void printhead(register int ac, register char **av);
69 void xobject(FILE *fp, char *nm);
70
71
72 int
73 main( /* compute illum distributions using rtrace */
74 int argc,
75 char *argv[]
76 )
77 {
78 int nprocs = 1;
79 char *rtpath;
80 FILE *fp;
81 register int i;
82 /* set global arguments */
83 gargv = argv;
84 /* check for -n option */
85 if (!strcmp(argv[1], "-n")) {
86 nprocs = atoi(argv[2]);
87 if (nprocs <= 0)
88 error(USER, "illegal number of processes");
89 i = 3;
90 } else
91 i = 1;
92 /* set up rtrace command */
93 for ( ; i < argc; i++) {
94 if (argv[i][0] == '<' && argv[i][1] == '\0')
95 break;
96 rtargv[rtargc++] = argv[i];
97 if (argv[i][0] == '-' && argv[i][1] == 'w')
98 switch (argv[i][2]) {
99 case '\0':
100 warnings = !warnings;
101 break;
102 case '+':
103 case 'T': case 't':
104 case 'Y': case 'y':
105 case '1':
106 warnings = 1;
107 break;
108 case '-':
109 case 'F': case 'f':
110 case 'N': case 'n':
111 case '0':
112 warnings = 0;
113 break;
114 }
115 }
116 gargc = i;
117 if (!strcmp(rtargv[--rtargc], "-defaults"))
118 nprocs = 0;
119 if (nprocs > 1) { /* add persist file if parallel invocation */
120 rtargv[rtargc++] = "-PP";
121 rtargv[rtargc++] = mktemp(persistfn);
122 }
123 /* add "mandatory" rtrace options */
124 for (i = 0; myrtopts[i] != NULL; i++)
125 rtargv[rtargc++] = myrtopts[i];
126 /* finally, put back final argument */
127 rtargv[rtargc++] = argv[gargc-1];
128 rtargv[rtargc] = NULL;
129 if (!nprocs) { /* just asking for defaults? */
130 printopts(); fflush(stdout);
131 rtpath = getpath(rtargv[0], getenv("PATH"), X_OK);
132 if (rtpath == NULL) {
133 eputs(rtargv[0]);
134 eputs(": command not found\n");
135 exit(1);
136 }
137 execv(rtpath, rtargv);
138 perror(rtpath); /* execv() should not return */
139 exit(1);
140 }
141 if (gargc < 2 || argv[gargc-1][0] == '-')
142 error(USER, "missing octree argument");
143 /* else initialize and run our calculation */
144 init(nprocs);
145 if (gargc+1 < argc)
146 for (i = gargc+1; i < argc; i++) {
147 if ((fp = fopen(argv[i], "r")) == NULL) {
148 sprintf(errmsg,
149 "cannot open scene file \"%s\"", argv[i]);
150 error(SYSTEM, errmsg);
151 }
152 filter(fp, argv[i]);
153 fclose(fp);
154 }
155 else
156 filter(stdin, "standard input");
157 quit(0);
158 }
159
160 static void
161 killpersist(void) /* kill persistent rtrace process */
162 {
163 FILE *fp = fopen(persistfn, "r");
164 int pid;
165
166 if (fp == NULL)
167 return;
168 if (fscanf(fp, "%*s %d", &pid) != 1 || kill(pid, SIGALRM) < 0)
169 unlink(persistfn);
170 fclose(fp);
171 }
172
173 void
174 quit(int status) /* exit with status */
175 {
176 struct rtproc *rtp;
177 int rtstat;
178
179 if (rt0.next != NULL) /* terminate persistent rtrace */
180 killpersist();
181 /* clean up rtrace process(es) */
182 for (rtp = &rt0; rtp != NULL; rtp = rtp->next) {
183 rtstat = close_process(&rtp->pd);
184 if (status == 0) {
185 if (rtstat < 0)
186 error(WARNING,
187 "unknown return status from rtrace process");
188 else
189 status = rtstat;
190 }
191 }
192 exit(status);
193 }
194
195 void
196 init(int np) /* start rtrace and set up buffers */
197 {
198 struct rtproc *rtp;
199 int i;
200 int maxbytes;
201 /* set up object functions */
202 ofun[OBJ_FACE].funp = o_face;
203 ofun[OBJ_SPHERE].funp = o_sphere;
204 ofun[OBJ_RING].funp = o_ring;
205 /* set up signal handling */
206 #ifdef SIGPIPE /* not present on Windows */
207 signal(SIGPIPE, quit);
208 #endif
209 rtp = &rt0; /* start rtrace process(es) */
210 for (i = 0; i++ < np; ) {
211 errno = 0;
212 maxbytes = open_process(&rtp->pd, rtargv);
213 if (maxbytes == 0) {
214 eputs(rtargv[0]);
215 eputs(": command not found\n");
216 exit(1);
217 }
218 if (maxbytes < 0)
219 error(SYSTEM, "cannot start rtrace process");
220 if (!i && np > 1)
221 sleep(2); /* wait for persist file */
222 rtp->bsiz = maxbytes/(6*sizeof(float));
223 rtp->buf = (float *)malloc(6*sizeof(float)*rtp->bsiz--);
224 rtp->dest = (float **)calloc(rtp->bsiz, sizeof(float *));
225 if (rtp->buf == NULL || rtp->dest == NULL)
226 error(SYSTEM, "out of memory in init");
227 rtp->nrays = 0;
228 if (i == np) /* last process? */
229 break;
230 rtp->next = (struct rtproc *)malloc(sizeof(struct rtproc));
231 if (rtp->next == NULL)
232 error(SYSTEM, "out of memory in init");
233 rtp = rtp->next;
234 }
235 rtp->next = NULL;
236 /* set up urand */
237 initurand(16384);
238 }
239
240
241 void
242 eputs( /* put string to stderr */
243 register char *s
244 )
245 {
246 static int midline = 0;
247
248 if (!*s) return;
249 if (!midline) {
250 fputs(progname, stderr);
251 fputs(": ", stderr);
252 }
253 fputs(s, stderr);
254 midline = s[strlen(s)-1] != '\n';
255 }
256
257
258 void
259 wputs(s) /* print warning if enabled */
260 char *s;
261 {
262 if (warnings)
263 eputs(s);
264 }
265
266
267 void
268 filter( /* process stream */
269 register FILE *infp,
270 char *name
271 )
272 {
273 char buf[512];
274 FILE *pfp;
275 register int c;
276
277 while ((c = getc(infp)) != EOF) {
278 if (isspace(c))
279 continue;
280 if (c == '#') { /* comment/options */
281 buf[0] = c;
282 fgets(buf+1, sizeof(buf)-1, infp);
283 xoptions(buf, name);
284 } else if (c == '!') { /* command */
285 buf[0] = c;
286 fgetline(buf+1, sizeof(buf)-1, infp);
287 if ((pfp = popen(buf+1, "r")) == NULL) {
288 sprintf(errmsg, "cannot execute \"%s\"", buf);
289 error(SYSTEM, errmsg);
290 }
291 filter(pfp, buf);
292 pclose(pfp);
293 } else { /* object */
294 ungetc(c, infp);
295 xobject(infp, name);
296 }
297 }
298 }
299
300
301 void
302 xoptions( /* process options in string s */
303 char *s,
304 char *nm
305 )
306 {
307 extern FILE *freopen();
308 char buf[64];
309 int nerrs = 0;
310 register char *cp;
311
312 if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
313 fputs(s, stdout); /* not for us */
314 return;
315 }
316 cp = s+10;
317 while (*cp) {
318 switch (*cp) {
319 case ' ':
320 case '\t':
321 case '\n':
322 case '\r':
323 case '\f':
324 cp++;
325 continue;
326 case 'm': /* material name */
327 if (*++cp != '=')
328 break;
329 if (!*++cp || isspace(*cp))
330 break;
331 atos(thisillum.matname, MAXSTR, cp);
332 cp = sskip(cp);
333 if (!(thisillum.flags & IL_DATCLB)) {
334 strcpy(thisillum.datafile, thisillum.matname);
335 thisillum.dfnum = 0;
336 }
337 continue;
338 case 'f': /* data file name */
339 if (*++cp != '=')
340 break;
341 if (!*++cp || isspace(*cp)) {
342 strcpy(thisillum.datafile,thisillum.matname);
343 thisillum.dfnum = 0;
344 thisillum.flags &= ~IL_DATCLB;
345 continue;
346 }
347 atos(thisillum.datafile, MAXSTR, cp);
348 cp = sskip(cp);
349 thisillum.dfnum = 0;
350 thisillum.flags |= IL_DATCLB;
351 continue;
352 case 'i': /* include material */
353 case 'e': /* exclude material */
354 if (cp[1] != '=')
355 break;
356 matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
357 cp += 2;
358 atos(matcheck, MAXSTR, cp);
359 cp = sskip(cp);
360 continue;
361 case 'a': /* use everything */
362 cp = sskip(cp);
363 matselect = S_ALL;
364 continue;
365 case 'n': /* use nothing (passive) */
366 cp = sskip(cp);
367 matselect = S_NONE;
368 continue;
369 case 'c': /* color calculation */
370 if (*++cp != '=')
371 break;
372 switch (*++cp) {
373 case 'a': /* average */
374 thisillum.flags = (thisillum.flags|IL_COLAVG)
375 & ~IL_COLDST;
376 break;
377 case 'd': /* distribution */
378 thisillum.flags |= (IL_COLDST|IL_COLAVG);
379 break;
380 case 'n': /* none */
381 thisillum.flags &= ~(IL_COLAVG|IL_COLDST);
382 break;
383 default:
384 goto opterr;
385 }
386 cp = sskip(cp);
387 continue;
388 case 'd': /* point sample density */
389 if (*++cp != '=')
390 break;
391 if (!isintd(++cp, " \t\n\r"))
392 break;
393 thisillum.sampdens = atoi(cp);
394 cp = sskip(cp);
395 continue;
396 case 's': /* point super-samples */
397 if (*++cp != '=')
398 break;
399 if (!isintd(++cp, " \t\n\r"))
400 break;
401 thisillum.nsamps = atoi(cp);
402 cp = sskip(cp);
403 continue;
404 case 'l': /* light sources */
405 cp++;
406 if (*cp == '+')
407 thisillum.flags |= IL_LIGHT;
408 else if (*cp == '-')
409 thisillum.flags &= ~IL_LIGHT;
410 else
411 break;
412 cp++;
413 continue;
414 case 'b': /* brightness */
415 if (*++cp != '=')
416 break;
417 if (!isfltd(++cp, " \t\n\r"))
418 break;
419 thisillum.minbrt = atof(cp);
420 if (thisillum.minbrt < 0.)
421 thisillum.minbrt = 0.;
422 cp = sskip(cp);
423 continue;
424 case 'o': /* output file */
425 if (*++cp != '=')
426 break;
427 if (!*++cp || isspace(*cp))
428 break;
429 atos(buf, sizeof(buf), cp);
430 cp = sskip(cp);
431 if (freopen(buf, "w", stdout) == NULL) {
432 sprintf(errmsg,
433 "cannot open output file \"%s\"", buf);
434 error(SYSTEM, errmsg);
435 }
436 doneheader = 0;
437 continue;
438 case '!': /* processed file! */
439 sprintf(errmsg, "(%s): already processed!", nm);
440 error(WARNING, errmsg);
441 matselect = S_NONE;
442 return;
443 }
444 opterr: /* skip faulty option */
445 while (*cp && !isspace(*cp))
446 cp++;
447 nerrs++;
448 }
449 /* print header? */
450 checkhead();
451 /* issue warnings? */
452 if (nerrs) {
453 sprintf(errmsg, "(%s): %d error(s) in option line:",
454 nm, nerrs);
455 error(WARNING, errmsg);
456 wputs(s);
457 printf("# %s: the following option line has %d error(s):\n",
458 progname, nerrs);
459 }
460 /* print pure comment */
461 printf("# %s", s+2);
462 }
463
464 void
465 printopts(void) /* print out option default values */
466 {
467 printf("m=%-15s\t\t# material name\n", thisillum.matname);
468 printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
469 if (thisillum.flags & IL_COLAVG)
470 if (thisillum.flags & IL_COLDST)
471 printf("c=d\t\t\t\t# color distribution\n");
472 else
473 printf("c=a\t\t\t\t# color average\n");
474 else
475 printf("c=n\t\t\t\t# color none\n");
476 if (thisillum.flags & IL_LIGHT)
477 printf("l+\t\t\t\t# light type on\n");
478 else
479 printf("l-\t\t\t\t# light type off\n");
480 printf("d=%d\t\t\t\t# density of points\n", thisillum.sampdens);
481 printf("s=%d\t\t\t\t# samples per point\n", thisillum.nsamps);
482 printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
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 (*ofun[thisobj.otype].funp)(&thisobj, &thisillum, &rt0, nm);
557 else
558 printobj(thisillum.altmat, &thisobj);
559 /* free arguments */
560 freefargs(&thisobj.oargs);
561 return;
562 readerr:
563 sprintf(errmsg, "(%s): error reading scene", nm);
564 error(USER, errmsg);
565 }