ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtmain.c
Revision: 2.7
Committed: Mon Jul 14 20:02:30 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.6: +2 -4 lines
Log Message:
Moved some more platform dependencies to common header files.
Included a few necessary system headers.

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 schorsch 2.7 static const char RCSid[] = "$Id: rtmain.c,v 2.6 2003/06/30 14:59:12 schorsch Exp $";
3 greg 2.1 #endif
4     /*
5     * rtmain.c - main for rtrace per-ray calculation program
6     */
7    
8 greg 2.2 #include "copyright.h"
9 greg 2.1
10 schorsch 2.4 #include <sys/types.h>
11     #include <signal.h>
12    
13     #include "platform.h"
14 schorsch 2.7 #include "rtprocess.h" /* getpid() */
15 greg 2.1 #include "ray.h"
16     #include "source.h"
17     #include "ambient.h"
18     #include "random.h"
19     #include "paths.h"
20    
21     /* persistent processes define */
22     #ifdef F_SETLKW
23     #define PERSIST 1 /* normal persist */
24     #define PARALLEL 2 /* parallel persist */
25     #define PCHILD 3 /* child of normal persist */
26     #endif
27    
28     char *progname; /* argv[0] */
29    
30     char *octname; /* octree name */
31    
32     char *sigerr[NSIG]; /* signal error messages */
33    
34     char *shm_boundary = NULL; /* boundary of shared memory */
35    
36     char *errfile = NULL; /* error output file */
37    
38     extern char *formstr(); /* string from format */
39     extern int inform; /* input format */
40     extern int outform; /* output format */
41     extern char *outvals; /* output values */
42    
43     extern int hresolu; /* horizontal resolution */
44     extern int vresolu; /* vertical resolution */
45    
46     extern int imm_irrad; /* compute immediate irradiance? */
47     extern int lim_dist; /* limit distance? */
48    
49     extern char *tralist[]; /* list of modifers to trace (or no) */
50     extern int traincl; /* include == 1, exclude == 0 */
51    
52     void onsig();
53     void sigdie();
54     void printdefaults();
55    
56    
57     int
58     main(argc, argv)
59     int argc;
60     char *argv[];
61     {
62     #define check(ol,al) if (argv[i][ol] || \
63     badarg(argc-i-1,argv+i+1,al)) \
64     goto badopt
65     #define bool(olen,var) switch (argv[i][olen]) { \
66     case '\0': var = !var; break; \
67     case 'y': case 'Y': case 't': case 'T': \
68     case '+': case '1': var = 1; break; \
69     case 'n': case 'N': case 'f': case 'F': \
70     case '-': case '0': var = 0; break; \
71     default: goto badopt; }
72     int loadflags = ~IO_FILES;
73     int persist = 0;
74     char **tralp;
75     int duped1;
76     int rval;
77     int i;
78     /* global program name */
79     progname = argv[0] = fixargv0(argv[0]);
80     /* option city */
81     for (i = 1; i < argc; i++) {
82     /* expand arguments */
83     while ((rval = expandarg(&argc, &argv, i)) > 0)
84     ;
85     if (rval < 0) {
86     sprintf(errmsg, "cannot expand '%s'", argv[i]);
87     error(SYSTEM, errmsg);
88     }
89     if (argv[i] == NULL || argv[i][0] != '-')
90     break; /* break from options */
91     if (!strcmp(argv[i], "-version")) {
92     puts(VersionID);
93     quit(0);
94     }
95     if (!strcmp(argv[i], "-defaults") ||
96     !strcmp(argv[i], "-help")) {
97     printdefaults();
98     quit(0);
99     }
100     rval = getrenderopt(argc-i, argv+i);
101     if (rval >= 0) {
102     i += rval;
103     continue;
104     }
105     switch (argv[i][1]) {
106     case 'x': /* x resolution */
107     check(2,"i");
108     hresolu = atoi(argv[++i]);
109     break;
110     case 'y': /* y resolution */
111     check(2,"i");
112     vresolu = atoi(argv[++i]);
113     break;
114     case 'w': /* warnings */
115     rval = erract[WARNING].pf != NULL;
116     bool(2,rval);
117     if (rval) erract[WARNING].pf = wputs;
118     else erract[WARNING].pf = NULL;
119     break;
120     case 'e': /* error file */
121     check(2,"s");
122     errfile = argv[++i];
123     break;
124     case 'l': /* limit distance */
125     if (argv[i][2] != 'd')
126     goto badopt;
127     bool(3,lim_dist);
128     break;
129     case 'I': /* immed. irradiance */
130     bool(2,imm_irrad);
131     break;
132     case 'f': /* format i/o */
133     switch (argv[i][2]) {
134     case 'a': /* ascii */
135     case 'f': /* float */
136     case 'd': /* double */
137     inform = argv[i][2];
138     break;
139     default:
140     goto badopt;
141     }
142     switch (argv[i][3]) {
143     case '\0':
144     outform = inform;
145     break;
146     case 'a': /* ascii */
147     case 'f': /* float */
148     case 'd': /* double */
149     case 'c': /* color */
150     check(4,"");
151     outform = argv[i][3];
152     break;
153     default:
154     goto badopt;
155     }
156     break;
157     case 'o': /* output */
158     outvals = argv[i]+2;
159     break;
160     case 'h': /* header output */
161     rval = loadflags & IO_INFO;
162     bool(2,rval);
163     loadflags = rval ? loadflags | IO_INFO :
164     loadflags & ~IO_INFO;
165     break;
166     case 't': /* trace */
167     switch (argv[i][2]) {
168     case 'i': /* include */
169     case 'I':
170     check(3,"s");
171     if (traincl != 1) {
172     traincl = 1;
173     tralp = tralist;
174     }
175     if (argv[i][2] == 'I') { /* file */
176     rval = wordfile(tralp,
177 greg 2.3 getpath(argv[++i],getrlibpath(),R_OK));
178 greg 2.1 if (rval < 0) {
179     sprintf(errmsg,
180     "cannot open trace include file \"%s\"",
181     argv[i]);
182     error(SYSTEM, errmsg);
183     }
184     tralp += rval;
185     } else {
186     *tralp++ = argv[++i];
187     *tralp = NULL;
188     }
189     break;
190     case 'e': /* exclude */
191     case 'E':
192     check(3,"s");
193     if (traincl != 0) {
194     traincl = 0;
195     tralp = tralist;
196     }
197     if (argv[i][2] == 'E') { /* file */
198     rval = wordfile(tralp,
199 greg 2.3 getpath(argv[++i],getrlibpath(),R_OK));
200 greg 2.1 if (rval < 0) {
201     sprintf(errmsg,
202     "cannot open trace exclude file \"%s\"",
203     argv[i]);
204     error(SYSTEM, errmsg);
205     }
206     tralp += rval;
207     } else {
208     *tralp++ = argv[++i];
209     *tralp = NULL;
210     }
211     break;
212     default:
213     goto badopt;
214     }
215     break;
216     #ifdef PERSIST
217     case 'P': /* persist file */
218     if (argv[i][2] == 'P') {
219     check(3,"s");
220     persist = PARALLEL;
221     } else {
222     check(2,"s");
223     persist = PERSIST;
224     }
225     persistfile(argv[++i]);
226     break;
227     #endif
228     default:
229     goto badopt;
230     }
231     }
232     /* initialize object types */
233     initotypes();
234     /* initialize urand */
235     initurand(2048);
236     /* set up signal handling */
237     sigdie(SIGINT, "Interrupt");
238 schorsch 2.5 #ifdef SIGHUP
239 greg 2.1 sigdie(SIGHUP, "Hangup");
240 schorsch 2.5 #endif
241 greg 2.1 sigdie(SIGTERM, "Terminate");
242 schorsch 2.5 #ifdef SIGPIPE
243 greg 2.1 sigdie(SIGPIPE, "Broken pipe");
244 schorsch 2.5 #endif
245     #ifdef SIGALRM
246 greg 2.1 sigdie(SIGALRM, "Alarm clock");
247 schorsch 2.5 #endif
248 greg 2.1 #ifdef SIGXCPU
249     sigdie(SIGXCPU, "CPU limit exceeded");
250     sigdie(SIGXFSZ, "File size exceeded");
251     #endif
252     /* open error file */
253     if (errfile != NULL) {
254     if (freopen(errfile, "a", stderr) == NULL)
255     quit(2);
256     fprintf(stderr, "**************\n*** PID %5d: ",
257     getpid());
258     printargs(argc, argv, stderr);
259     putc('\n', stderr);
260     fflush(stderr);
261     }
262     #ifdef NICE
263     nice(NICE); /* lower priority */
264     #endif
265     /* get octree */
266     if (i == argc)
267     octname = NULL;
268     else if (i == argc-1)
269     octname = argv[i];
270     else
271     goto badopt;
272     if (octname == NULL)
273     error(USER, "missing octree argument");
274     /* set up output */
275     #ifdef PERSIST
276     if (persist) {
277     duped1 = dup(fileno(stdout)); /* don't lose our output */
278     openheader();
279     }
280     #endif
281 schorsch 2.4 #ifdef _WIN32
282 greg 2.1 if (outform != 'a')
283 schorsch 2.4 SET_FILE_BINARY(stdout);
284 greg 2.1 if (octname == NULL)
285 schorsch 2.4 SET_FILE_BINARY(stdin);
286 greg 2.1 #endif
287     readoct(octname, loadflags, &thescene, NULL);
288     nsceneobjs = nobjects;
289    
290     if (loadflags & IO_INFO) { /* print header */
291     printargs(i, argv, stdout);
292     printf("SOFTWARE= %s\n", VersionID);
293     fputnow(stdout);
294     fputformat(formstr(outform), stdout);
295     putchar('\n');
296     }
297    
298     marksources(); /* find and mark sources */
299    
300     setambient(); /* initialize ambient calculation */
301    
302     #ifdef PERSIST
303     if (persist) {
304     fflush(stdout);
305     /* reconnect stdout */
306     dup2(duped1, fileno(stdout));
307     close(duped1);
308     if (persist == PARALLEL) { /* multiprocessing */
309     preload_objs(); /* preload scene */
310     shm_boundary = (char *)malloc(16);
311     strcpy(shm_boundary, "SHM_BOUNDARY");
312     while ((rval=fork()) == 0) { /* keep on forkin' */
313     pflock(1);
314     pfhold();
315     }
316     if (rval < 0)
317     error(SYSTEM, "cannot fork child for persist function");
318     pfdetach(); /* parent exits */
319     }
320     }
321     runagain:
322     if (persist)
323     dupheader(); /* send header to stdout */
324     #endif
325     /* trace rays */
326     rtrace(NULL);
327     /* flush ambient file */
328     ambsync();
329     #ifdef PERSIST
330     if (persist == PERSIST) { /* first run-through */
331     if ((rval=fork()) == 0) { /* child loops until killed */
332     pflock(1);
333     persist = PCHILD;
334     } else { /* original process exits */
335     if (rval < 0)
336     error(SYSTEM, "cannot fork child for persist function");
337     pfdetach(); /* parent exits */
338     }
339     }
340     if (persist == PCHILD) { /* wait for a signal then go again */
341     close(duped1); /* release output handle */
342     pfhold();
343     raynum = nrays = 0; /* reinitialize */
344     goto runagain;
345     }
346     #endif
347     quit(0);
348    
349     badopt:
350     sprintf(errmsg, "command line error at '%s'", argv[i]);
351     error(USER, errmsg);
352    
353     #undef check
354     #undef bool
355     }
356    
357    
358     void
359     wputs(s) /* warning output function */
360     char *s;
361     {
362     int lasterrno = errno;
363     eputs(s);
364     errno = lasterrno;
365     }
366    
367    
368     void
369     eputs(s) /* put string to stderr */
370     register char *s;
371     {
372     static int midline = 0;
373    
374     if (!*s)
375     return;
376     if (!midline++) {
377     fputs(progname, stderr);
378     fputs(": ", stderr);
379     }
380     fputs(s, stderr);
381     if (s[strlen(s)-1] == '\n') {
382     fflush(stderr);
383     midline = 0;
384     }
385     }
386    
387    
388     void
389     onsig(signo) /* fatal signal */
390     int signo;
391     {
392     static int gotsig = 0;
393    
394     if (gotsig++) /* two signals and we're gone! */
395     _exit(signo);
396    
397 schorsch 2.5 #ifdef SIGALRM
398 greg 2.1 alarm(15); /* allow 15 seconds to clean up */
399     signal(SIGALRM, SIG_DFL); /* make certain we do die */
400 schorsch 2.5 #endif
401 greg 2.1 eputs("signal - ");
402     eputs(sigerr[signo]);
403     eputs("\n");
404     quit(3);
405     }
406    
407    
408     void
409     sigdie(signo, msg) /* set fatal signal */
410     int signo;
411     char *msg;
412     {
413     if (signal(signo, onsig) == SIG_IGN)
414     signal(signo, SIG_IGN);
415     sigerr[signo] = msg;
416     }
417    
418    
419     void
420     printdefaults() /* print default values to stdout */
421     {
422     register char *cp;
423    
424     if (imm_irrad)
425     printf("-I+\t\t\t\t# immediate irradiance on\n");
426     printf("-x %-9d\t\t\t# x resolution\n", hresolu);
427     printf("-y %-9d\t\t\t# y resolution\n", vresolu);
428     printf(lim_dist ? "-ld+\t\t\t\t# limit distance on\n" :
429     "-ld-\t\t\t\t# limit distance off\n");
430     printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
431     inform, outform, formstr(inform), formstr(outform));
432     printf("-o%s\t\t\t\t# output", outvals);
433     for (cp = outvals; *cp; cp++)
434     switch (*cp) {
435     case 't': printf(" trace"); break;
436     case 'o': printf(" origin"); break;
437     case 'd': printf(" direction"); break;
438     case 'v': printf(" value"); break;
439     case 'l': printf(" length"); break;
440     case 'L': printf(" first_length"); break;
441     case 'p': printf(" point"); break;
442     case 'n': printf(" normal"); break;
443     case 'N': printf(" unperturbed_normal"); break;
444     case 's': printf(" surface"); break;
445     case 'w': printf(" weight"); break;
446     case 'm': printf(" modifier"); break;
447     }
448     putchar('\n');
449     printf(erract[WARNING].pf != NULL ?
450     "-w+\t\t\t\t# warning messages on\n" :
451     "-w-\t\t\t\t# warning messages off\n");
452     print_rdefaults();
453     }