ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo.c
Revision: 3.2
Committed: Fri Oct 31 11:44:09 1997 UTC (26 years, 6 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.1: +9 -7 lines
Log Message:
initial bug fixes

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 (%ld rays) done after %.2f hours\n",
231 progname, npacksdone, nraysdone, (t-starttime)/3600.);
232 fflush(stderr);
233 reporttime = t + (time_t)(vflt(REPORT)*60.);
234 }
235
236
237 setdefaults(gp) /* set default values */
238 register HDGRID *gp;
239 {
240 extern char *atos();
241 register int i;
242 double len[3], maxlen, d;
243 char buf[64];
244
245 if (!vdef(SECTION)) {
246 sprintf(errmsg, "%s must be defined", vnam(SECTION));
247 error(USER, errmsg);
248 }
249 if (vdef(SECTION) > 1) {
250 sprintf(errmsg, "ignoring all but first %s", vnam(SECTION));
251 error(WARNING, errmsg);
252 }
253 if (sscanf(vval(SECTION),
254 "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
255 &gp->orig[0], &gp->orig[1], &gp->orig[2],
256 &gp->xv[0][0], &gp->xv[0][1], &gp->xv[0][2],
257 &gp->xv[1][0], &gp->xv[1][1], &gp->xv[1][2],
258 &gp->xv[2][0], &gp->xv[2][1], &gp->xv[2][2]) != 12)
259 badvalue(SECTION);
260 maxlen = 0.;
261 for (i = 0; i < 3; i++)
262 if ((len[i] = VLEN(gp->xv[i])) > maxlen)
263 maxlen = len[i];
264 if (!vdef(GRID)) {
265 sprintf(buf, "%.4f", maxlen/8.);
266 vval(GRID) = savqstr(buf);
267 vdef(GRID)++;
268 }
269 if ((d = vflt(GRID)) <= FTINY)
270 badvalue(GRID);
271 for (i = 0; i < 3; i++)
272 gp->grid[i] = len[i]/d + (1.-FTINY);
273 if (!vdef(EXPOSURE)) {
274 sprintf(errmsg, "%s must be defined", vnam(EXPOSURE));
275 error(USER, errmsg);
276 }
277 expval = vval(EXPOSURE)[0] == '-' || vval(EXPOSURE)[0] == '+' ?
278 pow(2., vflt(EXPOSURE)) : vflt(EXPOSURE);
279 if (!vdef(OCTREE)) {
280 if ((vval(OCTREE) = bmalloc(strlen(froot)+5)) == NULL)
281 error(SYSTEM, "out of memory");
282 sprintf(vval(OCTREE), "%s.oct", froot);
283 vdef(OCTREE)++;
284 }
285 if (!vdef(DISKSPACE)) {
286 sprintf(errmsg,
287 "no %s setting, assuming 100 Mbytes available",
288 vnam(DISKSPACE));
289 error(WARNING, errmsg);
290 vval(DISKSPACE) = "100";
291 vdef(DISKSPACE)++;
292 }
293 if (!vdef(CACHE)) {
294 sprintf(errmsg,
295 "no %s setting, assuming 10 Mbytes available",
296 vnam(CACHE));
297 error(WARNING, errmsg);
298 vval(CACHE) = "10";
299 vdef(CACHE)++;
300 }
301 if (!vdef(OBSTRUCTIONS)) {
302 vval(OBSTRUCTIONS) = "T";
303 vdef(OBSTRUCTIONS)++;
304 }
305 if (!vdef(OCCUPANCY)) {
306 vval(OCCUPANCY) = "U";
307 vdef(OCCUPANCY)++;
308 }
309 /* append rendering options */
310 if (vdef(RENDER))
311 rtargc += wordstring(rtargv+rtargc, vval(RENDER));
312 }
313
314
315 creatholo(gp) /* create a holodeck output file */
316 HDGRID *gp;
317 {
318 long endloc = 0;
319 FILE *fp;
320 /* open & truncate file */
321 if ((fp = fopen(hdkfile, "w+")) == NULL) {
322 sprintf(errmsg, "cannot open \"%s\" for writing", hdkfile);
323 error(SYSTEM, errmsg);
324 }
325 /* write information header */
326 newheader("RADIANCE", fp);
327 printvars(fp);
328 fputformat(HOLOFMT, fp);
329 fputc('\n', fp);
330 putw(HOLOMAGIC, fp); /* put magic number & terminus */
331 fwrite(&endloc, sizeof(long), 1, fp);
332 fflush(fp); /* flush buffer */
333 hdinit(fileno(fp), gp); /* allocate and initialize index */
334 /* we're dropping fp here.... */
335 }
336
337
338 headline(s) /* process information header line */
339 char *s;
340 {
341 extern char FMTSTR[];
342 register char *cp;
343 char fmt[32];
344
345 if (formatval(fmt, s)) {
346 if (strcmp(fmt, HOLOFMT)) {
347 sprintf(errmsg, "%s file \"%s\" has %s%s",
348 HOLOFMT, hdkfile, FMTSTR, fmt);
349 error(USER, errmsg);
350 }
351 return;
352 }
353 for (cp = s; *cp; cp++) /* take off any comments */
354 if (*cp == '#') {
355 *cp = '\0';
356 break;
357 }
358 setvariable(s, matchvar); /* don't flag errors */
359 }
360
361
362 loadholo() /* start loading a holodeck from fname */
363 {
364 FILE *fp;
365 long endloc;
366 /* open input file */
367 if ((fp = fopen(hdkfile, "r+")) == NULL) {
368 sprintf(errmsg, "cannot open \"%s\" for appending", hdkfile);
369 error(SYSTEM, errmsg);
370 }
371 /* load variables from header */
372 getheader(fp, headline, NULL);
373 /* check magic number */
374 if (getw(fp) != HOLOMAGIC) {
375 sprintf(errmsg, "bad magic number in holodeck file \"%s\"",
376 hdkfile);
377 error(USER, errmsg);
378 }
379 fread(&endloc, sizeof(long), 1, fp);
380 if (endloc != 0)
381 error(WARNING, "ignoring multiple sections in holodeck file");
382 fseek(fp, 0L, 1); /* align system file pointer */
383 hdinit(fileno(fp), NULL); /* allocate and load index */
384 /* we're dropping fp here.... */
385 }
386
387
388 done_packets(pl) /* handle finished packets */
389 PACKET *pl;
390 {
391 register PACKET *p;
392
393 while (pl != NULL) {
394 p = pl; pl = p->next; p->next = NULL;
395 if (p->nr > 0) { /* add to holodeck */
396 bcopy((char *)p->ra,
397 (char *)hdnewrays(hdlist[p->hd],p->bi,p->nr),
398 p->nr*sizeof(RAYVAL));
399 if (outdev != NULL) /* display it */
400 disp_packet(p);
401 }
402 nraysdone += p->nr;
403 npacksdone++;
404 p->nr = 0; /* push onto free list */
405 p->next = freepacks;
406 freepacks = p;
407 }
408 }
409
410
411 getradfile(rfargs) /* run rad and get needed variables */
412 char *rfargs;
413 {
414 static short mvar[] = {VIEW,OCTREE,EXPOSURE,-1};
415 static char tf1[] = TEMPLATE;
416 char tf2[64];
417 char combuf[256];
418 register int i;
419 register char *cp;
420 /* create rad command */
421 mktemp(tf1);
422 sprintf(tf2, "%s.rif", tf1);
423 sprintf(combuf,
424 "rad -v 0 -s -e -w %s OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
425 rfargs, tf1);
426 cp = combuf;
427 while (*cp) cp++; /* match unset variables */
428 for (i = 0; mvar[i] >= 0; i++)
429 if (!vdef(mvar[i])) {
430 *cp++ = '|';
431 strcpy(cp, vnam(mvar[i]));
432 while (*cp) cp++;
433 }
434 sprintf(cp, ")[ \t]*=' > %s", tf2);
435 if (system(combuf)) {
436 error(SYSTEM, "cannot execute rad command");
437 unlink(tf2); /* clean up */
438 unlink(tf1);
439 quit(1);
440 }
441 loadvars(tf2); /* load variables */
442 rtargc += wordfile(rtargv+rtargc, tf1); /* get rtrace options */
443 unlink(tf2); /* clean up */
444 unlink(tf1);
445 }
446
447
448 rootname(rn, fn) /* remove tail from end of fn */
449 register char *rn, *fn;
450 {
451 char *tp, *dp;
452
453 for (tp = NULL, dp = rn; *rn = *fn++; rn++)
454 if (ISDIRSEP(*rn))
455 dp = rn;
456 else if (*rn == '.')
457 tp = rn;
458 if (tp != NULL && tp > dp)
459 *tp = '\0';
460 }
461
462
463 badvalue(vc) /* report bad variable value and exit */
464 int vc;
465 {
466 sprintf(errmsg, "bad value for variable '%s'", vnam(vc));
467 error(USER, errmsg);
468 }
469
470
471 eputs(s) /* put error message to stderr */
472 register char *s;
473 {
474 static int midline = 0;
475
476 if (!*s)
477 return;
478 if (!midline++) { /* prepend line with program name */
479 fputs(progname, stderr);
480 fputs(": ", stderr);
481 }
482 fputs(s, stderr);
483 if (s[strlen(s)-1] == '\n') {
484 fflush(stderr);
485 midline = 0;
486 }
487 }
488
489
490 wputs(s) /* put warning string to stderr */
491 char *s;
492 {
493 if (!nowarn)
494 eputs(s);
495 }
496
497
498 quit(ec) /* exit program gracefully */
499 int ec;
500 {
501 int status = 0;
502
503 if (hdlist[0] != NULL) { /* flush holodeck */
504 if (ncprocs > 0) {
505 done_packets(flush_queue());
506 status = end_rtrace(); /* close rtrace */
507 hdflush(NULL);
508 if (vdef(REPORT)) {
509 long fsiz, fuse;
510 report(0);
511 fsiz = lseek(hdlist[0]->fd, 0L, 2);
512 fuse = hdfiluse(hdlist[0]->fd, 1);
513 fprintf(stderr,
514 "%s: %.1f Mbyte holodeck file, %.2f%% fragmentation\n",
515 hdkfile, fsiz/(1024.*1024.),
516 100.*(fsiz-fuse)/fsiz);
517 }
518 } else
519 hdflush(NULL);
520 }
521 exit(ec ? ec : status); /* exit */
522 }