ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpmain.c
Revision: 2.27
Committed: Tue Aug 15 01:19:37 2023 UTC (9 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4
Changes since 2.26: +3 -1 lines
Log Message:
fix(rcontrib): Removed participating media from rcontrib -features

File Contents

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