ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpmain.c
Revision: 2.7
Committed: Mon Jul 21 22:30:19 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.6: +3 -2 lines
Log Message:
Eliminated copystruct() macro, which is unnecessary in ANSI.
Reduced ambiguity warnings for nested if/if/else clauses.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rpmain.c,v 2.6 2003/07/14 20:02:30 schorsch Exp $";
3 #endif
4 /*
5 * rpmain.c - main for rpict batch rendering 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 #include "view.h"
21
22 /* persistent processes define */
23 #ifdef F_SETLKW
24 #define PERSIST 1 /* normal persist */
25 #define PARALLEL 2 /* parallel persist */
26 #define PCHILD 3 /* child of normal persist */
27 #endif
28
29 char *progname; /* argv[0] */
30
31 char *octname; /* octree name */
32
33 char *sigerr[NSIG]; /* signal error messages */
34
35 char *shm_boundary = NULL; /* boundary of shared memory */
36
37 char *errfile = NULL; /* error output file */
38
39 extern time_t time();
40 extern time_t tstart; /* start time */
41
42 extern int ralrm; /* seconds between reports */
43
44 extern VIEW ourview; /* viewing parameters */
45
46 extern int hresolu; /* horizontal resolution */
47 extern int vresolu; /* vertical resolution */
48 extern double pixaspect; /* pixel aspect ratio */
49
50 extern int psample; /* pixel sample size */
51 extern double maxdiff; /* max. sample difference */
52 extern double dstrpix; /* square pixel distribution */
53
54 extern double mblur; /* motion blur parameter */
55
56 void onsig();
57 void sigdie();
58 void printdefaults();
59
60
61 int
62 main(argc, argv)
63 int argc;
64 char *argv[];
65 {
66 #define check(ol,al) if (argv[i][ol] || \
67 badarg(argc-i-1,argv+i+1,al)) \
68 goto badopt
69 #define bool(olen,var) switch (argv[i][olen]) { \
70 case '\0': var = !var; break; \
71 case 'y': case 'Y': case 't': case 'T': \
72 case '+': case '1': var = 1; break; \
73 case 'n': case 'N': case 'f': case 'F': \
74 case '-': case '0': var = 0; break; \
75 default: goto badopt; }
76 char *err;
77 char *recover = NULL;
78 char *outfile = NULL;
79 char *zfile = NULL;
80 int loadflags = ~IO_FILES;
81 int seqstart = 0;
82 int persist = 0;
83 int duped1;
84 int rval;
85 int i;
86 /* record start time */
87 tstart = time((time_t *)NULL);
88 /* global program name */
89 progname = argv[0] = fixargv0(argv[0]);
90 /* option city */
91 for (i = 1; i < argc; i++) {
92 /* expand arguments */
93 while ((rval = expandarg(&argc, &argv, i)) > 0)
94 ;
95 if (rval < 0) {
96 sprintf(errmsg, "cannot expand '%s'", argv[i]);
97 error(SYSTEM, errmsg);
98 }
99 if (argv[i] == NULL || argv[i][0] != '-')
100 break; /* break from options */
101 if (!strcmp(argv[i], "-version")) {
102 puts(VersionID);
103 quit(0);
104 }
105 if (!strcmp(argv[i], "-defaults") ||
106 !strcmp(argv[i], "-help")) {
107 printdefaults();
108 quit(0);
109 }
110 rval = getrenderopt(argc-i, argv+i);
111 if (rval >= 0) {
112 i += rval;
113 continue;
114 }
115 rval = getviewopt(&ourview, argc-i, argv+i);
116 if (rval >= 0) {
117 i += rval;
118 continue;
119 }
120 /* rpict options */
121 switch (argv[i][1]) {
122 case 'v': /* view file */
123 if (argv[i][2] != 'f')
124 goto badopt;
125 check(3,"s");
126 rval = viewfile(argv[++i], &ourview, NULL);
127 if (rval < 0) {
128 sprintf(errmsg,
129 "cannot open view file \"%s\"",
130 argv[i]);
131 error(SYSTEM, errmsg);
132 } else if (rval == 0) {
133 sprintf(errmsg,
134 "bad view file \"%s\"",
135 argv[i]);
136 error(USER, errmsg);
137 }
138 break;
139 case 'p': /* pixel */
140 switch (argv[i][2]) {
141 case 's': /* sample */
142 check(3,"i");
143 psample = atoi(argv[++i]);
144 break;
145 case 't': /* threshold */
146 check(3,"f");
147 maxdiff = atof(argv[++i]);
148 break;
149 case 'j': /* jitter */
150 check(3,"f");
151 dstrpix = atof(argv[++i]);
152 break;
153 case 'a': /* aspect */
154 check(3,"f");
155 pixaspect = atof(argv[++i]);
156 break;
157 case 'm': /* motion */
158 check(3,"f");
159 mblur = atof(argv[++i]);
160 break;
161 default:
162 goto badopt;
163 }
164 break;
165 case 'x': /* x resolution */
166 check(2,"i");
167 hresolu = atoi(argv[++i]);
168 break;
169 case 'y': /* y resolution */
170 check(2,"i");
171 vresolu = atoi(argv[++i]);
172 break;
173 case 'S': /* slave index */
174 check(2,"i");
175 seqstart = atoi(argv[++i]);
176 break;
177 case 'o': /* output file */
178 check(2,"s");
179 outfile = argv[++i];
180 break;
181 case 'z': /* z file */
182 check(2,"s");
183 zfile = argv[++i];
184 break;
185 case 'r': /* recover file */
186 if (argv[i][2] == 'o') { /* +output */
187 check(3,"s");
188 outfile = argv[i+1];
189 } else
190 check(2,"s");
191 recover = argv[++i];
192 break;
193 case 't': /* timer */
194 check(2,"i");
195 ralrm = atoi(argv[++i]);
196 break;
197 #ifdef PERSIST
198 case 'P': /* persist file */
199 if (argv[i][2] == 'P') {
200 check(3,"s");
201 persist = PARALLEL;
202 } else {
203 check(2,"s");
204 persist = PERSIST;
205 }
206 persistfile(argv[++i]);
207 break;
208 #endif
209 case 'w': /* warnings */
210 rval = erract[WARNING].pf != NULL;
211 bool(2,rval);
212 if (rval) erract[WARNING].pf = wputs;
213 else erract[WARNING].pf = NULL;
214 break;
215 case 'e': /* error file */
216 check(2,"s");
217 errfile = argv[++i];
218 break;
219 default:
220 goto badopt;
221 }
222 }
223 err = setview(&ourview); /* set viewing parameters */
224 if (err != NULL)
225 error(USER, err);
226 /* initialize object types */
227 initotypes();
228 /* initialize urand */
229 initurand(2048);
230 /* set up signal handling */
231 sigdie(SIGINT, "Interrupt");
232 #ifdef SIGHUP
233 sigdie(SIGHUP, "Hangup");
234 #endif
235 sigdie(SIGTERM, "Terminate");
236 #ifdef SIGPIPE
237 sigdie(SIGPIPE, "Broken pipe");
238 #endif
239 #ifdef SIGALRM
240 sigdie(SIGALRM, "Alarm clock");
241 #endif
242 #ifdef SIGXCPU
243 sigdie(SIGXCPU, "CPU limit exceeded");
244 sigdie(SIGXFSZ, "File size exceeded");
245 #endif
246 /* open error file */
247 if (errfile != NULL) {
248 if (freopen(errfile, "a", stderr) == NULL)
249 quit(2);
250 fprintf(stderr, "**************\n*** PID %5d: ",
251 getpid());
252 printargs(argc, argv, stderr);
253 putc('\n', stderr);
254 fflush(stderr);
255 }
256 #ifdef NICE
257 nice(NICE); /* lower priority */
258 #endif
259 /* get octree */
260 if (i == argc)
261 octname = NULL;
262 else if (i == argc-1)
263 octname = argv[i];
264 else
265 goto badopt;
266 if (seqstart > 0 && octname == NULL)
267 error(USER, "missing octree argument");
268 /* set up output */
269 #ifdef PERSIST
270 if (persist) {
271 if (recover != NULL)
272 error(USER, "persist option used with recover file");
273 if (seqstart <= 0)
274 error(USER, "persist option only for sequences");
275 if (outfile == NULL)
276 duped1 = dup(fileno(stdout)); /* don't lose our output */
277 openheader();
278 } else
279 #endif
280 if (outfile != NULL)
281 openheader();
282 #ifdef _WIN32
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 }
294
295 marksources(); /* find and mark sources */
296
297 setambient(); /* initialize ambient calculation */
298
299 #ifdef PERSIST
300 if (persist) {
301 fflush(stdout);
302 if (outfile == NULL) { /* reconnect stdout */
303 dup2(duped1, fileno(stdout));
304 close(duped1);
305 }
306 if (persist == PARALLEL) { /* multiprocessing */
307 preload_objs(); /* preload scene */
308 shm_boundary = (char *)malloc(16);
309 strcpy(shm_boundary, "SHM_BOUNDARY");
310 while ((rval=fork()) == 0) { /* keep on forkin' */
311 pflock(1);
312 pfhold();
313 tstart = time((time_t *)NULL);
314 }
315 if (rval < 0)
316 error(SYSTEM, "cannot fork child for persist function");
317 pfdetach(); /* parent exits */
318 }
319 }
320 runagain:
321 if (persist) {
322 if (outfile == NULL) /* if out to stdout */
323 dupheader(); /* send header */
324 else /* if out to file */
325 duped1 = dup(fileno(stdout)); /* hang onto pipe */
326 }
327 #endif
328 /* batch render picture(s) */
329 rpict(seqstart, outfile, zfile, recover);
330 /* flush ambient file */
331 ambsync();
332 #ifdef PERSIST
333 if (persist == PERSIST) { /* first run-through */
334 if ((rval=fork()) == 0) { /* child loops until killed */
335 pflock(1);
336 persist = PCHILD;
337 } else { /* original process exits */
338 if (rval < 0)
339 error(SYSTEM, "cannot fork child for persist function");
340 pfdetach(); /* parent exits */
341 }
342 }
343 if (persist == PCHILD) { /* wait for a signal then go again */
344 if (outfile != NULL)
345 close(duped1); /* release output handle */
346 pfhold();
347 tstart = time((time_t *)NULL); /* reinitialize */
348 raynum = nrays = 0;
349 goto runagain;
350 }
351 #endif
352 quit(0);
353
354 badopt:
355 sprintf(errmsg, "command line error at '%s'", argv[i]);
356 error(USER, errmsg);
357
358 #undef check
359 #undef bool
360 }
361
362
363 void
364 wputs(s) /* warning output function */
365 char *s;
366 {
367 int lasterrno = errno;
368 eputs(s);
369 errno = lasterrno;
370 }
371
372
373 void
374 eputs(s) /* put string to stderr */
375 register char *s;
376 {
377 static int midline = 0;
378
379 if (!*s)
380 return;
381 if (!midline++) {
382 fputs(progname, stderr);
383 fputs(": ", stderr);
384 }
385 fputs(s, stderr);
386 if (s[strlen(s)-1] == '\n') {
387 fflush(stderr);
388 midline = 0;
389 }
390 }
391
392
393 void
394 onsig(signo) /* fatal signal */
395 int signo;
396 {
397 static int gotsig = 0;
398
399 if (gotsig++) /* two signals and we're gone! */
400 _exit(signo);
401
402 #ifdef SIGALRM /* XXX how critical is this? */
403 alarm(15); /* allow 15 seconds to clean up */
404 signal(SIGALRM, SIG_DFL); /* make certain we do die */
405 #endif
406 eputs("signal - ");
407 eputs(sigerr[signo]);
408 eputs("\n");
409 quit(3);
410 }
411
412
413 void
414 sigdie(signo, msg) /* set fatal signal */
415 int signo;
416 char *msg;
417 {
418 if (signal(signo, onsig) == SIG_IGN)
419 signal(signo, SIG_IGN);
420 sigerr[signo] = msg;
421 }
422
423
424 void
425 printdefaults() /* print default values to stdout */
426 {
427 printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
428 ourview.type==VT_PER ? "perspective" :
429 ourview.type==VT_PAR ? "parallel" :
430 ourview.type==VT_HEM ? "hemispherical" :
431 ourview.type==VT_ANG ? "angular" :
432 ourview.type==VT_CYL ? "cylindrical" :
433 "unknown");
434 printf("-vp %f %f %f\t# view point\n",
435 ourview.vp[0], ourview.vp[1], ourview.vp[2]);
436 printf("-vd %f %f %f\t# view direction\n",
437 ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
438 printf("-vu %f %f %f\t# view up\n",
439 ourview.vup[0], ourview.vup[1], ourview.vup[2]);
440 printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
441 printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
442 printf("-vo %f\t\t\t# view fore clipping plane\n", ourview.vfore);
443 printf("-va %f\t\t\t# view aft clipping plane\n", ourview.vaft);
444 printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
445 printf("-vl %f\t\t\t# view lift\n", ourview.voff);
446 printf("-x %-9d\t\t\t# x resolution\n", hresolu);
447 printf("-y %-9d\t\t\t# y resolution\n", vresolu);
448 printf("-pa %f\t\t\t# pixel aspect ratio\n", pixaspect);
449 printf("-pj %f\t\t\t# pixel jitter\n", dstrpix);
450 printf("-pm %f\t\t\t# pixel motion\n", mblur);
451 printf("-ps %-9d\t\t\t# pixel sample\n", psample);
452 printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
453 printf("-t %-9d\t\t\t# time between reports\n", ralrm);
454 printf(erract[WARNING].pf != NULL ?
455 "-w+\t\t\t\t# warning messages on\n" :
456 "-w-\t\t\t\t# warning messages off\n");
457 print_rdefaults();
458 }