ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.1
Committed: Wed Nov 4 16:37:19 1998 UTC (25 years, 5 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# User Rev Content
1 gwlarson 3.1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ SGI";
5     #endif
6    
7     /*
8     * Optimize holodeck for quick access.
9     *
10     * 11/4/98 Greg Ward Larson
11     */
12    
13     #include "holo.h"
14    
15     #ifndef BKBSIZE
16     #define BKBSIZE 64 /* beam clump size (kilobytes) */
17     #endif
18    
19    
20     char *progname;
21    
22     extern long rhinitcopy();
23    
24    
25     main(argc, argv)
26     int argc;
27     char *argv[];
28     {
29     char nambuf[128];
30     char *inpname, *outname;
31     int hdfd[2];
32     long nextipos, lastopos, thisopos;
33    
34     progname = argv[0];
35     if (argc < 2 | argc > 3) {
36     fprintf(stderr, "Usage: %s input.hdk [output.hdk]\n", progname);
37     exit(1);
38     }
39     inpname = argv[1];
40     if (argc == 3) /* use given output file */
41     outname = argv[2];
42     else { /* else create temporary file */
43     strcpy(nambuf, inpname);
44     if ((outname = strrchr(nambuf, '/')) != NULL)
45     outname++;
46     else
47     outname = nambuf;
48     sprintf(outname, "rho%d.hdk", getpid());
49     outname = nambuf;
50     }
51     /* copy holodeck file header */
52     nextipos = rhinitcopy(hdfd, inpname, outname);
53     lastopos = 0L; /* copy sections one by one */
54     while (nextipos != 0L) {
55     /* set input position; get next */
56     lseek(hdfd[0], nextipos, 0);
57     read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
58     /* get output position; set last */
59     thisopos = lseek(hdfd[1], 0L, 2);
60     if (lastopos > 0L) {
61     lseek(hdfd[1], lastopos, 0);
62     write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
63     lseek(hdfd[1], 0L, 2);
64     }
65     lastopos = thisopos;
66     thisopos = 0L; /* write place holder */
67     write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
68     /* copy holodeck section */
69     copysect(hdfd[0], hdfd[1]);
70     }
71     /* clean up */
72     close(hdfd[0]);
73     close(hdfd[1]);
74     if (argc == 2 && rename(outname, inpname) < 0) {
75     sprintf(errmsg, "cannot rename \"%s\" to \"%s\"",
76     outname, inpname);
77     error(SYSTEM, errmsg);
78     }
79     exit(0);
80     }
81    
82    
83     long
84     rhinitcopy(hfd, infn, outfn) /* open files and copy header */
85     int hfd[2]; /* returned file descriptors */
86     char *infn, *outfn;
87     {
88     FILE *infp, *outfp;
89     long ifpos;
90     /* open files for i/o */
91     if ((infp = fopen(infn, "r")) == NULL) {
92     sprintf(errmsg, "cannot open \"%s\" for reading", infn);
93     error(SYSTEM, errmsg);
94     }
95     if ((outfp = fopen(outfn, "w+")) == NULL) {
96     sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
97     error(SYSTEM, errmsg);
98     }
99     /* copy and verify header */
100     if (checkheader(infp, HOLOFMT, outfp) < 0 ||
101     getw(infp) != HOLOMAGIC)
102     error(USER, "input not in holodeck format");
103     fputformat(HOLOFMT, outfp);
104     fputc('\n', outfp);
105     putw(HOLOMAGIC, outfp);
106     /* get descriptors and free stdio */
107     if ((hfd[0] = dup(fileno(infp))) < 0 ||
108     (hfd[1] = dup(fileno(outfp))) < 0)
109     error(SYSTEM, "dup call failed in rhinitcopy");
110     ifpos = ftell(infp);
111     fclose(infp);
112     if (fclose(outfp) == EOF)
113     error(SYSTEM, "file flushing error in rhinitcopy");
114     /* we flush everything manually */
115     hdcachesize = 0;
116     /* return input position */
117     return(ifpos);
118     }
119    
120    
121     gcshifti(gc, ia, di, hp) /* shift cell row or column */
122     register GCOORD *gc;
123     int ia, di;
124     register HOLO *hp;
125     {
126     int nw;
127    
128     if (di > 0) {
129     if (++gc->i[ia] >= hp->grid[((gc->w>>1)+1+ia)%3]) {
130     nw = ((gc->w&~1) + (ia<<1) + 3) % 6;
131     gc->i[ia] = gc->i[1-ia];
132     gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0;
133     gc->w = nw;
134     }
135     } else if (di < 0) {
136     if (--gc->i[ia] < 0) {
137     nw = ((gc->w&~1) + (ia<<1) + 2) % 6;
138     gc->i[ia] = gc->i[1-ia];
139     gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0;
140     gc->w = nw;
141     }
142     }
143     }
144    
145    
146     mkneighgrid(ng, hp, gc) /* compute neighborhood for grid cell */
147     GCOORD ng[3*3];
148     HOLO *hp;
149     GCOORD *gc;
150     {
151     GCOORD gci0;
152     int i, j;
153    
154     for (i = 3; i--; ) {
155     copystruct(&gci0, gc);
156     gcshifti(&gci0, 0, i-1, hp);
157     for (j = 3; j--; ) {
158     copystruct(ng+(3*i+j), &gci0);
159     gcshifti(ng+(3*i+j), 1, j-1, hp);
160     }
161     }
162     }
163    
164    
165     int bneighlist[9*9-1];
166     int bneighrem;
167    
168     #define nextneigh() (bneighrem<=0 ? 0 : bneighlist[--bneighrem])
169    
170     int
171     firstneigh(hp, b) /* initialize neighbor list and return first */
172     HOLO *hp;
173     int b;
174     {
175     GCOORD wg0[9], wg1[9], bgc[2];
176     int i, j;
177    
178     hdbcoord(bgc, hp, b);
179     mkneighgrid(wg0, hp, bgc);
180     mkneighgrid(wg1, hp, bgc+1);
181     bneighrem = 0;
182     for (i = 9; i--; )
183     for (j = 9; j--; ) {
184     if (i == 4 & j == 4)
185     continue;
186     copystruct(bgc, wg0+i);
187     copystruct(bgc+1, wg1+j);
188     bneighlist[bneighrem++] = hdbindex(hp, bgc);
189     }
190     return(nextneigh());
191     }
192    
193    
194     copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */
195     int ifd, ofd;
196     {
197     #define beamdone(b) (!hinp->bi[b].nrd || bnrays(hout,b))
198     static short primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1};
199     register HOLO *hinp, *hout;
200     register BEAM *bp;
201     int *bqueue;
202     int bqlen;
203     int4 bqtotal;
204     int bc, bci, bqc, bnc, myprime;
205     register int i;
206     /* load input section directory */
207     hinp = hdinit(ifd, NULL);
208     /* create output section directory */
209     hout = hdinit(ofd, (HDGRID *)hinp);
210     /* allocate beam queue */
211     if ((bqueue = (int *)malloc(nbeams(hinp)*sizeof(int))) == NULL)
212     error(SYSTEM, "out of memory in copysect");
213     /* pick a good prime step size */
214     for (i = 0; primes[i]<<5 >= nbeams(hinp); i++)
215     ;
216     while ((myprime = primes[i++]) > 1)
217     if (nbeams(hinp) % myprime)
218     break;
219     /* add each input beam and neighbors */
220     for (bc = bci = nbeams(hinp); bc > 0; bc--,
221     bci += bci>myprime ? -myprime : nbeams(hinp)-myprime) {
222     if (beamdone(bci))
223     continue;
224     bqueue[0] = bci; /* initialize queue */
225     bqlen = 1;
226     bqtotal = bnrays(hinp, bci);
227     /* run through growing queue */
228     for (bqc = 0; bqc < bqlen; bqc++) {
229     /* transfer the beam */
230     bp = hdgetbeam(hinp, bqueue[bqc]);
231     bcopy((char *)hdbray(bp),
232     (char *)hdnewrays(hout,bqueue[bqc],bp->nrm),
233     bp->nrm*sizeof(RAYVAL));
234     hdfreebeam(hinp, bqueue[bqc]);
235     /* check queue size */
236     if (bqtotal >= BKBSIZE*1024/sizeof(RAYVAL))
237     continue;
238     /* add neighbors to queue */
239     for (bnc = firstneigh(hinp,bqueue[bqc]); bnc > 0;
240     bnc = nextneigh()) {
241     if (beamdone(bnc)) /* see if valid */
242     continue;
243     for (i = bqlen; i--; )
244     if (bqueue[i] == bnc) break;
245     if (i >= 0)
246     continue;
247     bqueue[bqlen++] = bnc; /* add it */
248     bqtotal += bnrays(hinp, bnc);
249     if (bqtotal >= BKBSIZE*1024/sizeof(RAYVAL))
250     break; /* queue full */
251     }
252     }
253     hdfreebeam(hout, 0); /* flush output block */
254     }
255     /* we're done -- clean up */
256     free((char *)bqueue);
257     hddone(hinp);
258     hddone(hout);
259     #undef beamdone
260     }
261    
262    
263     eputs(s) /* put error message to stderr */
264     register char *s;
265     {
266     static int midline = 0;
267    
268     if (!*s)
269     return;
270     if (!midline++) { /* prepend line with program name */
271     fputs(progname, stderr);
272     fputs(": ", stderr);
273     }
274     fputs(s, stderr);
275     if (s[strlen(s)-1] == '\n') {
276     fflush(stderr);
277     midline = 0;
278     }
279     }
280    
281    
282     quit(code) /* exit the program gracefully */
283     int code;
284     {
285     hdsync(NULL, 1); /* write out any buffered data */
286     exit(code);
287     }