ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.26
Committed: Mon Sep 19 11:30:10 2005 UTC (18 years, 7 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.25: +6 -1 lines
Log Message:
Removed SPEED from SCons. Changes to build with mingw, as suggested by Francesco Anselmo.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: mkillum.c,v 2.25 2005/05/26 14:46:21 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 "mkillum.h"
13 #include "random.h"
14
15 /* default parameters */
16 #define SAMPDENS 48 /* points per projected steradian */
17 #define NSAMPS 32 /* samples per point */
18 #define DFLMAT "illum_mat" /* material name */
19 #define DFLDAT "illum" /* data file name */
20 /* selection options */
21 #define S_NONE 0 /* select none */
22 #define S_ELEM 1 /* select specified element */
23 #define S_COMPL 2 /* select all but element */
24 #define S_ALL 3 /* select all */
25
26 /* rtrace command and defaults */
27 char *rtargv[64] = { "rtrace", "-dj", ".25", "-dr", "3", "-dv-",
28 "-ab", "2", "-ad", "1024", "-as", "512", "-aa", ".1", };
29 int rtargc = 14;
30 /* overriding rtrace options */
31 char *myrtopts[] = { "-I-", "-i-", "-ld-", "-ov", "-h-",
32 "-fff", "-y", "0", NULL };
33
34 struct rtproc rt0; /* head of rtrace process list */
35
36 struct illum_args thisillum = { /* our illum and default values */
37 0,
38 DFLMAT,
39 DFLDAT,
40 0,
41 VOIDID,
42 SAMPDENS,
43 NSAMPS,
44 0.,
45 };
46
47 char matcheck[MAXSTR]; /* current material to include or exclude */
48 int matselect = S_ALL; /* selection criterion */
49
50 FUN ofun[NUMOTYPE] = INIT_OTYPE; /* object types */
51
52 char persistfn[] = "pfXXXXXX"; /* persist file name */
53
54 int gargc; /* global argc */
55 char **gargv; /* global argv */
56 #define progname gargv[0]
57
58 int doneheader = 0; /* printed header yet? */
59 #define checkhead() if (!doneheader++) printhead(gargc,gargv)
60
61 int warnings = 1; /* print warnings? */
62
63 int done_rprocs(struct rtproc *rtp);
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
161 #ifndef SIGALRM
162 #define SIGALRM SIGTERM
163 #endif
164 static void
165 killpersist(void) /* kill persistent rtrace process */
166 {
167 FILE *fp = fopen(persistfn, "r");
168 int pid;
169
170 if (fp == NULL)
171 return;
172 if (fscanf(fp, "%*s %d", &pid) != 1 || kill(pid, SIGALRM) < 0)
173 unlink(persistfn);
174 fclose(fp);
175 }
176
177
178 int
179 done_rprocs(struct rtproc *rtp)
180 {
181 int st0, st1 = 0;
182
183 if (rtp->next != NULL) { /* close last opened first! */
184 st1 = done_rprocs(rtp->next);
185 free((void *)rtp->next);
186 rtp->next = NULL;
187 }
188 st0 = close_process(&rtp->pd);
189 if (st0 < 0)
190 error(WARNING, "unknown return status from rtrace process");
191 else if (st0 > 0)
192 return(st0);
193 return(st1);
194 }
195
196 void
197 quit(int status) /* exit with status */
198 {
199 int rtstat;
200
201 if (rt0.next != NULL) /* terminate persistent rtrace */
202 killpersist();
203 /* clean up rtrace process(es) */
204 rtstat = done_rprocs(&rt0);
205 if (status == 0)
206 status = rtstat;
207 exit(status);
208 }
209
210 void
211 init(int np) /* start rtrace and set up buffers */
212 {
213 struct rtproc *rtp;
214 int i;
215 int maxbytes;
216 /* set up object functions */
217 ofun[OBJ_FACE].funp = o_face;
218 ofun[OBJ_SPHERE].funp = o_sphere;
219 ofun[OBJ_RING].funp = o_ring;
220 /* set up signal handling */
221 signal(SIGINT, quit);
222 #ifdef SIGHUP
223 signal(SIGHUP, quit);
224 #endif
225 #ifdef SIGTERM
226 signal(SIGTERM, quit);
227 #endif
228 #ifdef SIGPIPE
229 signal(SIGPIPE, quit);
230 #endif
231 rtp = &rt0; /* start rtrace process(es) */
232 for (i = 0; i++ < np; ) {
233 errno = 0;
234 maxbytes = open_process(&rtp->pd, rtargv);
235 if (maxbytes == 0) {
236 eputs(rtargv[0]);
237 eputs(": command not found\n");
238 exit(1);
239 }
240 if (maxbytes < 0)
241 error(SYSTEM, "cannot start rtrace process");
242 rtp->bsiz = maxbytes/(6*sizeof(float));
243 rtp->buf = (float *)malloc(6*sizeof(float)*rtp->bsiz--);
244 rtp->dest = (float **)calloc(rtp->bsiz, sizeof(float *));
245 if (rtp->buf == NULL || rtp->dest == NULL)
246 error(SYSTEM, "out of memory in init");
247 rtp->nrays = 0;
248 if (i == np) /* last process? */
249 break;
250 if (np > 1)
251 sleep(2); /* wait for persist file */
252 rtp->next = (struct rtproc *)malloc(sizeof(struct rtproc));
253 if (rtp->next == NULL)
254 error(SYSTEM, "out of memory in init");
255 rtp = rtp->next;
256 }
257 rtp->next = NULL;
258 /* set up urand */
259 initurand(16384);
260 }
261
262
263 void
264 eputs( /* put string to stderr */
265 register char *s
266 )
267 {
268 static int midline = 0;
269
270 if (!*s) return;
271 if (!midline) {
272 fputs(progname, stderr);
273 fputs(": ", stderr);
274 }
275 fputs(s, stderr);
276 midline = s[strlen(s)-1] != '\n';
277 }
278
279
280 void
281 wputs(s) /* print warning if enabled */
282 char *s;
283 {
284 if (warnings)
285 eputs(s);
286 }
287
288
289 void
290 filter( /* process stream */
291 register FILE *infp,
292 char *name
293 )
294 {
295 char buf[512];
296 FILE *pfp;
297 register int c;
298
299 while ((c = getc(infp)) != EOF) {
300 if (isspace(c))
301 continue;
302 if (c == '#') { /* comment/options */
303 buf[0] = c;
304 fgets(buf+1, sizeof(buf)-1, infp);
305 xoptions(buf, name);
306 } else if (c == '!') { /* command */
307 buf[0] = c;
308 fgetline(buf+1, sizeof(buf)-1, infp);
309 if ((pfp = popen(buf+1, "r")) == NULL) {
310 sprintf(errmsg, "cannot execute \"%s\"", buf);
311 error(SYSTEM, errmsg);
312 }
313 filter(pfp, buf);
314 pclose(pfp);
315 } else { /* object */
316 ungetc(c, infp);
317 xobject(infp, name);
318 }
319 }
320 }
321
322
323 void
324 xoptions( /* process options in string s */
325 char *s,
326 char *nm
327 )
328 {
329 extern FILE *freopen();
330 char buf[64];
331 int nerrs = 0;
332 register char *cp;
333
334 if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
335 fputs(s, stdout); /* not for us */
336 return;
337 }
338 cp = s+10;
339 while (*cp) {
340 switch (*cp) {
341 case ' ':
342 case '\t':
343 case '\n':
344 case '\r':
345 case '\f':
346 cp++;
347 continue;
348 case 'm': /* material name */
349 if (*++cp != '=')
350 break;
351 if (!*++cp || isspace(*cp))
352 break;
353 atos(thisillum.matname, MAXSTR, cp);
354 cp = sskip(cp);
355 if (!(thisillum.flags & IL_DATCLB)) {
356 strcpy(thisillum.datafile, thisillum.matname);
357 thisillum.dfnum = 0;
358 }
359 continue;
360 case 'f': /* data file name */
361 if (*++cp != '=')
362 break;
363 if (!*++cp || isspace(*cp)) {
364 strcpy(thisillum.datafile,thisillum.matname);
365 thisillum.dfnum = 0;
366 thisillum.flags &= ~IL_DATCLB;
367 continue;
368 }
369 atos(thisillum.datafile, MAXSTR, cp);
370 cp = sskip(cp);
371 thisillum.dfnum = 0;
372 thisillum.flags |= IL_DATCLB;
373 continue;
374 case 'i': /* include material */
375 case 'e': /* exclude material */
376 if (cp[1] != '=')
377 break;
378 matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
379 cp += 2;
380 atos(matcheck, MAXSTR, cp);
381 cp = sskip(cp);
382 continue;
383 case 'a': /* use everything */
384 cp = sskip(cp);
385 matselect = S_ALL;
386 continue;
387 case 'n': /* use nothing (passive) */
388 cp = sskip(cp);
389 matselect = S_NONE;
390 continue;
391 case 'c': /* color calculation */
392 if (*++cp != '=')
393 break;
394 switch (*++cp) {
395 case 'a': /* average */
396 thisillum.flags = (thisillum.flags|IL_COLAVG)
397 & ~IL_COLDST;
398 break;
399 case 'd': /* distribution */
400 thisillum.flags |= (IL_COLDST|IL_COLAVG);
401 break;
402 case 'n': /* none */
403 thisillum.flags &= ~(IL_COLAVG|IL_COLDST);
404 break;
405 default:
406 goto opterr;
407 }
408 cp = sskip(cp);
409 continue;
410 case 'd': /* point sample density */
411 if (*++cp != '=')
412 break;
413 if (!isintd(++cp, " \t\n\r"))
414 break;
415 thisillum.sampdens = atoi(cp);
416 cp = sskip(cp);
417 continue;
418 case 's': /* point super-samples */
419 if (*++cp != '=')
420 break;
421 if (!isintd(++cp, " \t\n\r"))
422 break;
423 thisillum.nsamps = atoi(cp);
424 cp = sskip(cp);
425 continue;
426 case 'l': /* light sources */
427 cp++;
428 if (*cp == '+')
429 thisillum.flags |= IL_LIGHT;
430 else if (*cp == '-')
431 thisillum.flags &= ~IL_LIGHT;
432 else
433 break;
434 cp++;
435 continue;
436 case 'b': /* brightness */
437 if (*++cp != '=')
438 break;
439 if (!isfltd(++cp, " \t\n\r"))
440 break;
441 thisillum.minbrt = atof(cp);
442 if (thisillum.minbrt < 0.)
443 thisillum.minbrt = 0.;
444 cp = sskip(cp);
445 continue;
446 case 'o': /* output file */
447 if (*++cp != '=')
448 break;
449 if (!*++cp || isspace(*cp))
450 break;
451 atos(buf, sizeof(buf), cp);
452 cp = sskip(cp);
453 if (freopen(buf, "w", stdout) == NULL) {
454 sprintf(errmsg,
455 "cannot open output file \"%s\"", buf);
456 error(SYSTEM, errmsg);
457 }
458 doneheader = 0;
459 continue;
460 case '!': /* processed file! */
461 sprintf(errmsg, "(%s): already processed!", nm);
462 error(WARNING, errmsg);
463 matselect = S_NONE;
464 return;
465 }
466 opterr: /* skip faulty option */
467 while (*cp && !isspace(*cp))
468 cp++;
469 nerrs++;
470 }
471 /* print header? */
472 checkhead();
473 /* issue warnings? */
474 if (nerrs) {
475 sprintf(errmsg, "(%s): %d error(s) in option line:",
476 nm, nerrs);
477 error(WARNING, errmsg);
478 wputs(s);
479 printf("# %s: the following option line has %d error(s):\n",
480 progname, nerrs);
481 }
482 /* print pure comment */
483 printf("# %s", s+2);
484 }
485
486 void
487 printopts(void) /* print out option default values */
488 {
489 printf("m=%-15s\t\t# material name\n", thisillum.matname);
490 printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
491 if (thisillum.flags & IL_COLAVG)
492 if (thisillum.flags & IL_COLDST)
493 printf("c=d\t\t\t\t# color distribution\n");
494 else
495 printf("c=a\t\t\t\t# color average\n");
496 else
497 printf("c=n\t\t\t\t# color none\n");
498 if (thisillum.flags & IL_LIGHT)
499 printf("l+\t\t\t\t# light type on\n");
500 else
501 printf("l-\t\t\t\t# light type off\n");
502 printf("d=%d\t\t\t\t# density of points\n", thisillum.sampdens);
503 printf("s=%d\t\t\t\t# samples per point\n", thisillum.nsamps);
504 printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
505 }
506
507
508 void
509 printhead( /* print out header */
510 register int ac,
511 register char **av
512 )
513 {
514 putchar('#');
515 while (ac-- > 0) {
516 putchar(' ');
517 fputs(*av++, stdout);
518 }
519 fputs("\n#@mkillum !\n", stdout);
520 }
521
522
523 void
524 xobject( /* translate an object from fp */
525 FILE *fp,
526 char *nm
527 )
528 {
529 OBJREC thisobj;
530 char str[MAXSTR];
531 int doit;
532 /* read the object */
533 if (fgetword(thisillum.altmat, MAXSTR, fp) == NULL)
534 goto readerr;
535 if (fgetword(str, MAXSTR, fp) == NULL)
536 goto readerr;
537 /* is it an alias? */
538 if (!strcmp(str, ALIASKEY)) {
539 if (fgetword(str, MAXSTR, fp) == NULL)
540 goto readerr;
541 printf("\n%s %s %s", thisillum.altmat, ALIASKEY, str);
542 if (fgetword(str, MAXSTR, fp) == NULL)
543 goto readerr;
544 printf("\t%s\n", str);
545 return;
546 }
547 thisobj.omod = OVOID; /* unused field */
548 if ((thisobj.otype = otype(str)) < 0) {
549 sprintf(errmsg, "(%s): unknown type \"%s\"", nm, str);
550 error(USER, errmsg);
551 }
552 if (fgetword(str, MAXSTR, fp) == NULL)
553 goto readerr;
554 thisobj.oname = str;
555 if (readfargs(&thisobj.oargs, fp) != 1)
556 goto readerr;
557 thisobj.os = NULL;
558 /* check for translation */
559 switch (matselect) {
560 case S_NONE:
561 doit = 0;
562 break;
563 case S_ALL:
564 doit = 1;
565 break;
566 case S_ELEM:
567 doit = !strcmp(thisillum.altmat, matcheck);
568 break;
569 case S_COMPL:
570 doit = strcmp(thisillum.altmat, matcheck);
571 break;
572 }
573 doit = doit && issurface(thisobj.otype);
574 /* print header? */
575 checkhead();
576 /* process object */
577 if (doit)
578 (*ofun[thisobj.otype].funp)(&thisobj, &thisillum, &rt0, nm);
579 else
580 printobj(thisillum.altmat, &thisobj);
581 /* free arguments */
582 freefargs(&thisobj.oargs);
583 return;
584 readerr:
585 sprintf(errmsg, "(%s): error reading scene", nm);
586 error(USER, errmsg);
587 }