ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo.c
Revision: 3.1
Committed: Fri Oct 31 10:23:29 1997 UTC (26 years, 6 months ago) by gregl
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1997 Silicon Graphics, Inc. */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ SGI";
5 #endif
6
7 /*
8 * Radiance holodeck generation controller
9 */
10
11 #include "rholo.h"
12 #include "paths.h"
13 #include <sys/types.h>
14
15 /* the following must be consistent with rholo.h */
16 int NVARS = NRHVARS; /* total number of variables */
17
18 VARIABLE vv[] = RHVINIT; /* variable-value pairs */
19
20 char *progname; /* our program name */
21 char *hdkfile; /* holodeck file name */
22 char froot[MAXPATH]; /* root file name */
23
24 int nowarn = 0; /* turn warnings off? */
25
26 double expval = 1.; /* global exposure value */
27
28 int ncprocs = 0; /* desired number of compute processes */
29
30 char *outdev = NULL; /* output device name */
31
32 time_t starttime; /* time we got started */
33 time_t endtime; /* time we should end by */
34 time_t reporttime; /* time for next report */
35
36 int rtargc = 1; /* rtrace command */
37 char *rtargv[128] = {"rtrace", NULL};
38
39 long nraysdone = 0L; /* number of rays done */
40 long npacksdone = 0L; /* number of packets done */
41
42 PACKET *freepacks; /* available packets */
43
44 extern time_t time();
45
46
47 main(argc, argv)
48 int argc;
49 char *argv[];
50 {
51 HDGRID hdg;
52 int i;
53 int force = 0;
54
55 progname = argv[0]; /* get arguments */
56 for (i = 1; i < argc && argv[i][0] == '-'; i++)
57 switch (argv[i][1]) {
58 case 'w': /* turn off warnings */
59 nowarn++;
60 break;
61 case 'f': /* force overwrite */
62 force++;
63 break;
64 case 'n': /* compute processes */
65 if (i >= argc-2)
66 goto userr;
67 ncprocs = atoi(argv[++i]);
68 break;
69 case 'o': /* output display */
70 if (i >= argc-2)
71 goto userr;
72 outdev = argv[++i];
73 break;
74 default:
75 goto userr;
76 }
77 /* do we have a job? */
78 if (outdev == NULL && ncprocs <= 0)
79 goto userr;
80 /* get root file name */
81 rootname(froot, hdkfile=argv[i++]);
82 /* load... */
83 if (i < argc) { /* variables */
84 loadvars(argv[i++]);
85 /* cmdline settings */
86 for ( ; i < argc; i++)
87 if (setvariable(argv[i], matchvar) < 0) {
88 sprintf(errmsg, "unknown variable: %s",
89 argv[i]);
90 error(USER, errmsg);
91 }
92 /* check settings */
93 checkvalues();
94 /* load RIF if any */
95 if (vdef(RIF))
96 getradfile(vval(RIF));
97 /* set defaults */
98 setdefaults(&hdg);
99 /* holodeck exists? */
100 if (!force && access(hdkfile, R_OK|W_OK) == 0)
101 error(USER,
102 "holodeck file exists -- use -f to overwrite");
103 /* create holodeck */
104 creatholo(&hdg);
105 } else /* else load holodeck */
106 loadholo();
107 /* initialize */
108 initrholo();
109 /* run */
110 while (rholo())
111 ;
112 /* done */
113 quit(0);
114 userr:
115 fprintf(stderr,
116 "Usage: %s {-n nprocs|-o disp} [-w][-f] output.hdk [control.hif [VAR=val ..]]\n",
117 progname);
118 quit(1);
119 }
120
121
122 initrholo() /* get our holodeck running */
123 {
124 extern int global_packet();
125 register int i;
126 /* check output device */
127 if (outdev != NULL)
128 open_display(outdev);
129 else if (ncprocs > 0) /* else use global ray feed */
130 init_global();
131 /* record the time */
132 starttime = time(NULL);
133 if (!vdef(TIME) || vflt(TIME) <= FTINY)
134 endtime = 0;
135 else
136 endtime = starttime + vflt(TIME)*3600.;
137 /* set up memory cache */
138 hdcachesize = 1024.*1024.*vflt(CACHE);
139 /* open report file */
140 if (vdef(REPORT)) {
141 register char *s = sskip2(vval(REPORT), 1);
142 if (*s && freopen(s, "a", stderr) == NULL)
143 quit(2);
144 }
145 /* start rtrace */
146 if (ncprocs > 0) {
147 i = start_rtrace();
148 if (i < 1)
149 error(USER, "cannot start rtrace process");
150 if (vdef(REPORT)) { /* make first report */
151 printargs(rtargc, rtargv, stderr);
152 report(0);
153 }
154 /* allocate packets */
155 freepacks = (PACKET *)bmalloc(i*sizeof(PACKET));
156 if (freepacks == NULL)
157 goto memerr;
158 freepacks[--i].nr = 0;
159 freepacks[i].next = NULL;
160 if (!vbool(OBSTRUCTIONS)) {
161 freepacks[i].offset = (float *)bmalloc(
162 RPACKSIZ*sizeof(float)*(i+1) );
163 if (freepacks[i].offset == NULL)
164 goto memerr;
165 } else
166 freepacks[i].offset = NULL;
167 while (i--) {
168 freepacks[i].nr = 0;
169 freepacks[i].offset = freepacks[i+1].offset == NULL ?
170 NULL : freepacks[i+1].offset+RPACKSIZ ;
171 freepacks[i].next = &freepacks[i+1];
172 }
173 }
174 return;
175 memerr:
176 error(SYSTEM, "out of memory in initrholo");
177 }
178
179
180 rholo() /* holodeck main loop */
181 {
182 static int idle = 1;
183 PACKET *pl = NULL, *plend;
184 register PACKET *p;
185 time_t t;
186 long l;
187 /* check display */
188 if (outdev != NULL && !disp_check(idle))
189 return(0);
190 /* display only? */
191 if (ncprocs <= 0)
192 return(1);
193 /* check file size */
194 if (l = 1024.*1024.*vflt(DISKSPACE) > 0 &&
195 hdfiluse(hdlist[0]->fd, 0) + hdmemuse(0) >= l)
196 return(0);
197 /* check time */
198 if (endtime > 0 || vdef(REPORT))
199 t = time(NULL);
200 if (endtime > 0 && t >= endtime)
201 return(0);
202 if (vdef(REPORT) && t >= reporttime)
203 report(t);
204 /* get packets to process */
205 while (freepacks != NULL) {
206 p = freepacks; freepacks = p->next; p->next = NULL;
207 if (!next_packet(p)) {
208 p->next = freepacks; freepacks = p;
209 break;
210 }
211 if (pl == NULL) pl = p;
212 else plend->next = p;
213 plend = p;
214 }
215 idle = pl == NULL && freepacks != NULL;
216 /* are we out of stuff to do? */
217 if (idle && outdev == NULL)
218 return(0);
219 /* else process packets */
220 done_packets(do_packets(pl));
221 return(1); /* and continue */
222 }
223
224
225 report(t) /* report progress so far */
226 time_t t;
227 {
228 if (t == 0)
229 t = time(NULL);
230 fprintf(stderr, "%s: %ld packets done (%ld rays) after %.2f hours\n",
231 progname, npacksdone, nraysdone, (t-starttime)/3600.);
232 }
233
234
235 setdefaults(gp) /* set default values */
236 register HDGRID *gp;
237 {
238 extern char *atos();
239 register int i;
240 double len[3], maxlen, d;
241 char buf[64];
242
243 if (!vdef(SECTION)) {
244 sprintf(errmsg, "%s must be defined", vnam(SECTION));
245 error(USER, errmsg);
246 }
247 if (vdef(SECTION) > 1) {
248 sprintf(errmsg, "ignoring all but first %s", vnam(SECTION));
249 error(WARNING, errmsg);
250 }
251 if (sscanf(vval(SECTION),
252 "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
253 &gp->orig[0], &gp->orig[1], &gp->orig[2],
254 &gp->xv[0][0], &gp->xv[0][1], &gp->xv[0][2],
255 &gp->xv[1][0], &gp->xv[1][1], &gp->xv[1][2],
256 &gp->xv[2][0], &gp->xv[2][1], &gp->xv[2][2]) != 12)
257 badvalue(SECTION);
258 maxlen = 0.;
259 for (i = 0; i < 3; i++)
260 if ((len[i] = VLEN(gp->xv[i])) > maxlen)
261 maxlen = len[i];
262 if (!vdef(GRID)) {
263 sprintf(buf, "%.4f", maxlen/16.);
264 vval(GRID) = savqstr(buf);
265 vdef(GRID)++;
266 }
267 if ((d = vflt(GRID)) <= FTINY)
268 badvalue(GRID);
269 for (i = 0; i < 3; i++)
270 gp->grid[i] = len[i]/d + (1.-FTINY);
271 if (!vdef(EXPOSURE)) {
272 sprintf(errmsg, "%s must be defined", vnam(EXPOSURE));
273 error(USER, errmsg);
274 }
275 expval = vval(EXPOSURE)[0] == '-' || vval(EXPOSURE)[0] == '+' ?
276 pow(2., vflt(EXPOSURE)) : vflt(EXPOSURE);
277 if (!vdef(OCTREE)) {
278 if ((vval(OCTREE) = bmalloc(strlen(froot)+5)) == NULL)
279 error(SYSTEM, "out of memory");
280 sprintf(vval(OCTREE), "%s.oct", froot);
281 vdef(OCTREE)++;
282 }
283 if (!vdef(DISKSPACE)) {
284 sprintf(errmsg,
285 "no %s setting, assuming 100 Mbytes available",
286 vnam(DISKSPACE));
287 error(WARNING, errmsg);
288 vval(DISKSPACE) = "100";
289 vdef(DISKSPACE)++;
290 }
291 if (!vdef(CACHE)) {
292 sprintf(errmsg,
293 "no %s setting, assuming 10 Mbytes available",
294 vnam(CACHE));
295 error(WARNING, errmsg);
296 vval(CACHE) = "10";
297 vdef(CACHE)++;
298 }
299 if (!vdef(OBSTRUCTIONS)) {
300 vval(OBSTRUCTIONS) = "T";
301 vdef(OBSTRUCTIONS)++;
302 }
303 if (!vdef(OCCUPANCY)) {
304 vval(OCCUPANCY) = "U";
305 vdef(OCCUPANCY)++;
306 }
307 /* append rendering options */
308 if (vdef(RENDER))
309 rtargc += wordstring(rtargv+rtargc, vval(RENDER));
310 }
311
312
313 creatholo(gp) /* create a holodeck output file */
314 HDGRID *gp;
315 {
316 long endloc = 0;
317 FILE *fp;
318 /* open & truncate file */
319 if ((fp = fopen(hdkfile, "w+")) == NULL) {
320 sprintf(errmsg, "cannot open \"%s\" for writing", hdkfile);
321 error(SYSTEM, errmsg);
322 }
323 /* write information header */
324 newheader("RADIANCE", fp);
325 printvars(fp);
326 fputformat(HOLOFMT, fp);
327 fputc('\n', fp);
328 putw(HOLOMAGIC, fp); /* put magic number & terminus */
329 fwrite(&endloc, sizeof(long), 1, fp);
330 fflush(fp); /* flush buffer */
331 initholo(fileno(fp), gp); /* allocate and initialize index */
332 /* we're dropping fp here.... */
333 }
334
335
336 headline(s) /* process information header line */
337 char *s;
338 {
339 extern char FMTSTR[];
340 register char *cp;
341 char fmt[32];
342
343 if (headidval(fmt, s)) {
344 if (strcmp(fmt, HOLOFMT)) {
345 sprintf(errmsg, "%s file \"%s\" has %s%s",
346 HOLOFMT, hdkfile, FMTSTR, fmt);
347 error(USER, errmsg);
348 }
349 return;
350 }
351 for (cp = s; *cp; cp++) /* take off any comments */
352 if (*cp == '#') {
353 *cp = '\0';
354 break;
355 }
356 setvariable(s, matchvar); /* don't flag errors */
357 }
358
359
360 loadholo() /* start loading a holodeck from fname */
361 {
362 FILE *fp;
363 long endloc;
364 /* open input file */
365 if ((fp = fopen(hdkfile, "r+")) == NULL) {
366 sprintf(errmsg, "cannot open \"%s\" for appending", hdkfile);
367 error(SYSTEM, errmsg);
368 }
369 /* load variables from header */
370 getheader(fp, headline, NULL);
371 /* check magic number */
372 if (getw(fp) != HOLOMAGIC) {
373 sprintf(errmsg, "bad magic number in holodeck file \"%s\"",
374 hdkfile);
375 error(USER, errmsg);
376 }
377 fread(&endloc, sizeof(long), 1, fp);
378 if (endloc != 0)
379 error(WARNING, "ignoring multiple sections in holodeck file");
380 fseek(fp, 0L, 1); /* align system file pointer */
381 initholo(fileno(fp), NULL); /* allocate and load index */
382 /* we're dropping fp here.... */
383 }
384
385
386 done_packets(pl) /* handle finished packets */
387 PACKET *pl;
388 {
389 register PACKET *p;
390
391 while (pl != NULL) {
392 p = pl; pl = p->next; p->next = NULL;
393 if (p->nr > 0) { /* add to holodeck */
394 bcopy((char *)p->ra,
395 (char *)hdnewrays(hdlist[p->hd],p->bi,p->nr),
396 p->nr*sizeof(RAYVAL));
397 if (outdev != NULL) /* display it */
398 disp_packet(p);
399 }
400 nraysdone += p->nr;
401 npacksdone++;
402 p->nr = 0; /* push onto free list */
403 p->next = freepacks;
404 freepacks = p;
405 }
406 }
407
408
409 getradfile(rfargs) /* run rad and get needed variables */
410 char *rfargs;
411 {
412 static short mvar[] = {VIEW,OCTREE,EXPOSURE,REPORT,-1};
413 static char tf1[] = TEMPLATE;
414 char tf2[64];
415 char combuf[256];
416 register int i;
417 register char *cp;
418 /* create rad command */
419 mktemp(tf1);
420 sprintf(tf2, "%s.rif", tf1);
421 sprintf(combuf,
422 "rad -v 0 -s -e -w %s OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
423 rfargs, tf1);
424 cp = combuf;
425 while (*cp) cp++; /* match unset variables */
426 for (i = 0; mvar[i] >= 0; i++)
427 if (!vdef(mvar[i])) {
428 *cp++ = '|';
429 strcpy(cp, vnam(mvar[i]));
430 while (*cp) cp++;
431 }
432 sprintf(cp, ")[ \t]*=' > %s", tf2);
433 if (system(combuf)) {
434 error(SYSTEM, "cannot execute rad command");
435 unlink(tf2); /* clean up */
436 unlink(tf1);
437 quit(1);
438 }
439 loadvars(tf2); /* load variables */
440 rtargc += wordfile(rtargv+rtargc, tf1); /* get rtrace options */
441 unlink(tf2); /* clean up */
442 unlink(tf1);
443 }
444
445
446 rootname(rn, fn) /* remove tail from end of fn */
447 register char *rn, *fn;
448 {
449 char *tp, *dp;
450
451 for (tp = NULL, dp = rn; *rn = *fn++; rn++)
452 if (ISDIRSEP(*rn))
453 dp = rn;
454 else if (*rn == '.')
455 tp = rn;
456 if (tp != NULL && tp > dp)
457 *tp = '\0';
458 }
459
460
461 badvalue(vc) /* report bad variable value and exit */
462 int vc;
463 {
464 sprintf(errmsg, "bad value for variable '%s'", vnam(vc));
465 error(USER, errmsg);
466 }
467
468
469 eputs(s) /* put error message to stderr */
470 register char *s;
471 {
472 static int midline = 0;
473
474 if (!*s)
475 return;
476 if (!midline++) { /* prepend line with program name */
477 fputs(progname, stderr);
478 fputs(": ", stderr);
479 }
480 fputs(s, stderr);
481 if (s[strlen(s)-1] == '\n') {
482 fflush(stderr);
483 midline = 0;
484 }
485 }
486
487
488 wputs(s) /* put warning string to stderr */
489 char *s;
490 {
491 if (!nowarn)
492 eputs(s);
493 }
494
495
496 quit(ec) /* exit program gracefully */
497 int ec;
498 {
499 int status = 0;
500
501 if (hdlist[0] != NULL) { /* flush holodeck */
502 if (ncprocs > 0) {
503 done_packets(flush_queue());
504 status = end_rtrace(); /* close rtrace */
505 hdflush(NULL);
506 if (vdef(REPORT)) {
507 long fsiz, fuse;
508 report(0);
509 fsiz = lseek(hdlist[0]->fd, 0L, 2);
510 fuse = hdfiluse(hdlist[0]->fd, 1);
511 fprintf(stderr,
512 "%s: %.1f Mbyte holodeck file, %.2f%% fragmentation\n",
513 hdkfile, fsiz/(1024.*1024.),
514 100.*(fsiz-fuse)/fsiz);
515 }
516 } else
517 hdflush(NULL);
518 }
519 exit(ec ? ec : status); /* exit */
520 }