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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rtmain.c,v 2.6 2003/06/30 14:59:12 schorsch Exp $";
3 #endif
4 /*
5 * rtmain.c - main for rtrace per-ray calculation program
6 */
7
8 #include "copyright.h"
9
10 #include <sys/types.h>
11 #include <signal.h>
12
13 #include "platform.h"
14 #include "rtprocess.h" /* getpid() */
15 #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 getpath(argv[++i],getrlibpath(),R_OK));
178 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 getpath(argv[++i],getrlibpath(),R_OK));
200 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 #ifdef SIGHUP
239 sigdie(SIGHUP, "Hangup");
240 #endif
241 sigdie(SIGTERM, "Terminate");
242 #ifdef SIGPIPE
243 sigdie(SIGPIPE, "Broken pipe");
244 #endif
245 #ifdef SIGALRM
246 sigdie(SIGALRM, "Alarm clock");
247 #endif
248 #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 #ifdef _WIN32
282 if (outform != 'a')
283 SET_FILE_BINARY(stdout);
284 if (octname == NULL)
285 SET_FILE_BINARY(stdin);
286 #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 #ifdef SIGALRM
398 alarm(15); /* allow 15 seconds to clean up */
399 signal(SIGALRM, SIG_DFL); /* make certain we do die */
400 #endif
401 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 }