ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.7
Committed: Mon Feb 1 09:56:18 1999 UTC (25 years, 2 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.6: +1 -1 lines
Log Message:
made caching code slightly more efficient

File Contents

# User Rev Content
1 gwlarson 3.6 /* Copyright (c) 1999 Silicon Graphics, Inc. */
2 gwlarson 3.1
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 gwlarson 3.3 #include <signal.h>
16    
17 gwlarson 3.1 #ifndef BKBSIZE
18 gwlarson 3.2 #define BKBSIZE 256 /* beam clump size (kilobytes) */
19 gwlarson 3.1 #endif
20    
21     char *progname;
22 gwlarson 3.3 char tempfile[128];
23 gwlarson 3.6 int dupchecking = 0;
24 gwlarson 3.1
25 gwlarson 3.3 extern char *rindex();
26     extern int quit();
27 gwlarson 3.1 extern long rhinitcopy();
28    
29    
30     main(argc, argv)
31     int argc;
32     char *argv[];
33     {
34     char *inpname, *outname;
35     int hdfd[2];
36     long nextipos, lastopos, thisopos;
37    
38     progname = argv[0];
39 gwlarson 3.6 argv++; argc--; /* duplicate checking flag? */
40     if (argc > 1 && !strcmp(argv[0], "-u")) {
41     dupchecking++;
42     argv++; argc--;
43     }
44     if (argc < 1 | argc > 2) {
45     fprintf(stderr, "Usage: %s [-u] input.hdk [output.hdk]\n",
46     progname);
47 gwlarson 3.1 exit(1);
48     }
49 gwlarson 3.6 inpname = argv[0]; /* get input file */
50     argv++; argc--;
51     if (argc == 1) /* use given output file */
52     outname = argv[0];
53 gwlarson 3.3 else { /* else use temporary file */
54     if (access(inpname, R_OK|W_OK) < 0) { /* check permissions */
55     sprintf(errmsg, "cannot access \"%s\"", inpname);
56     error(SYSTEM, errmsg);
57     }
58     strcpy(tempfile, inpname);
59     if ((outname = rindex(tempfile, '/')) != NULL)
60 gwlarson 3.1 outname++;
61     else
62 gwlarson 3.3 outname = tempfile;
63 gwlarson 3.1 sprintf(outname, "rho%d.hdk", getpid());
64 gwlarson 3.3 outname = tempfile;
65 gwlarson 3.1 }
66     /* copy holodeck file header */
67     nextipos = rhinitcopy(hdfd, inpname, outname);
68     lastopos = 0L; /* copy sections one by one */
69     while (nextipos != 0L) {
70     /* set input position; get next */
71     lseek(hdfd[0], nextipos, 0);
72     read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
73     /* get output position; set last */
74     thisopos = lseek(hdfd[1], 0L, 2);
75     if (lastopos > 0L) {
76     lseek(hdfd[1], lastopos, 0);
77     write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
78     lseek(hdfd[1], 0L, 2);
79     }
80     lastopos = thisopos;
81     thisopos = 0L; /* write place holder */
82     write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
83     /* copy holodeck section */
84     copysect(hdfd[0], hdfd[1]);
85     }
86     /* clean up */
87     close(hdfd[0]);
88     close(hdfd[1]);
89 gwlarson 3.3 if (outname == tempfile && rename(outname, inpname) < 0) {
90 gwlarson 3.1 sprintf(errmsg, "cannot rename \"%s\" to \"%s\"",
91     outname, inpname);
92     error(SYSTEM, errmsg);
93     }
94     exit(0);
95     }
96    
97    
98     long
99     rhinitcopy(hfd, infn, outfn) /* open files and copy header */
100     int hfd[2]; /* returned file descriptors */
101     char *infn, *outfn;
102     {
103     FILE *infp, *outfp;
104     long ifpos;
105     /* open files for i/o */
106     if ((infp = fopen(infn, "r")) == NULL) {
107     sprintf(errmsg, "cannot open \"%s\" for reading", infn);
108     error(SYSTEM, errmsg);
109     }
110     if ((outfp = fopen(outfn, "w+")) == NULL) {
111     sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
112     error(SYSTEM, errmsg);
113     }
114 gwlarson 3.3 /* set up signal handling */
115     if (signal(SIGINT, quit) == SIG_IGN) signal(SIGINT, SIG_IGN);
116     if (signal(SIGHUP, quit) == SIG_IGN) signal(SIGHUP, SIG_IGN);
117     if (signal(SIGTERM, quit) == SIG_IGN) signal(SIGTERM, SIG_IGN);
118     #ifdef SIGXCPU
119     if (signal(SIGXCPU, quit) == SIG_IGN) signal(SIGXCPU, SIG_IGN);
120     if (signal(SIGXFSZ, quit) == SIG_IGN) signal(SIGXFSZ, SIG_IGN);
121     #endif
122 gwlarson 3.1 /* copy and verify header */
123 gwlarson 3.3 if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC)
124 gwlarson 3.1 error(USER, "input not in holodeck format");
125     fputformat(HOLOFMT, outfp);
126     fputc('\n', outfp);
127     putw(HOLOMAGIC, outfp);
128     /* get descriptors and free stdio */
129     if ((hfd[0] = dup(fileno(infp))) < 0 ||
130     (hfd[1] = dup(fileno(outfp))) < 0)
131     error(SYSTEM, "dup call failed in rhinitcopy");
132     ifpos = ftell(infp);
133     fclose(infp);
134     if (fclose(outfp) == EOF)
135     error(SYSTEM, "file flushing error in rhinitcopy");
136 gwlarson 3.4 /* check cache size */
137     if (BKBSIZE*1024*1.5 > hdcachesize)
138     hdcachesize = BKBSIZE*1024*1.5;
139 gwlarson 3.1 /* return input position */
140     return(ifpos);
141     }
142    
143    
144 gwlarson 3.6 int
145     nuniq(rva, n) /* sort unique rays to front of beam list */
146     register RAYVAL *rva;
147     int n;
148     {
149     register int i, j;
150     RAYVAL rtmp;
151    
152     for (j = 0; j < n; j++)
153     for (i = j+1; i < n; i++)
154     if ( rva[i].d == rva[j].d &&
155     rva[i].r[0][0]==rva[j].r[0][0] &&
156     rva[i].r[0][1]==rva[j].r[0][1] &&
157     rva[i].r[1][0]==rva[j].r[1][0] &&
158     rva[i].r[1][1]==rva[j].r[1][1] ) {
159     n--; /* swap duplicate with end */
160     copystruct(&rtmp, rva+n);
161     copystruct(rva+n, rva+i);
162     copystruct(rva+i, &rtmp);
163     i--; /* recheck one we swapped */
164     }
165     return(n);
166     }
167    
168    
169 gwlarson 3.5 static BEAMI *beamdir;
170 gwlarson 3.1
171 gwlarson 3.4 static int
172 gwlarson 3.5 bpcmp(b1p, b2p) /* compare beam positions on disk */
173     int *b1p, *b2p;
174 gwlarson 3.1 {
175 gwlarson 3.5 register long pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
176    
177     if (pdif < 0L) return(-1);
178 gwlarson 3.6 return(pdif > 0L);
179 gwlarson 3.2 }
180    
181 gwlarson 3.5 static HOLO *hout;
182    
183     static int
184     xferclump(hp, bq, nb) /* transfer the given clump to hout and free */
185     HOLO *hp;
186     int *bq, nb;
187     {
188     register int i;
189     register BEAM *bp;
190 gwlarson 3.6 int n;
191 gwlarson 3.5
192     beamdir = hp->bi; /* sort based on file position */
193     qsort((char *)bq, nb, sizeof(*bq), bpcmp);
194     /* transfer and free each beam */
195     for (i = 0; i < nb; i++) {
196     bp = hdgetbeam(hp, bq[i]);
197 gwlarson 3.6 DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
198     n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
199     bcopy((char *)hdbray(bp), (char *)hdnewrays(hout,bq[i],n),
200     n*sizeof(RAYVAL));
201 gwlarson 3.5 hdfreebeam(hp, bq[i]);
202     }
203 gwlarson 3.7 hdfreebeam(hout, 0); /* write & free clump */
204 gwlarson 3.5 return(0);
205     }
206    
207 gwlarson 3.1 copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */
208     int ifd, ofd;
209     {
210 gwlarson 3.4 HOLO *hinp;
211 gwlarson 3.1 /* load input section directory */
212     hinp = hdinit(ifd, NULL);
213     /* create output section directory */
214     hout = hdinit(ofd, (HDGRID *)hinp);
215 gwlarson 3.4 /* clump the beams */
216 gwlarson 3.5 clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
217 gwlarson 3.4 /* clean up */
218 gwlarson 3.1 hddone(hinp);
219     hddone(hout);
220     }
221    
222    
223     eputs(s) /* put error message to stderr */
224     register char *s;
225     {
226     static int midline = 0;
227    
228     if (!*s)
229     return;
230     if (!midline++) { /* prepend line with program name */
231     fputs(progname, stderr);
232     fputs(": ", stderr);
233     }
234     fputs(s, stderr);
235     if (s[strlen(s)-1] == '\n') {
236     fflush(stderr);
237     midline = 0;
238     }
239     }
240    
241    
242     quit(code) /* exit the program gracefully */
243     int code;
244     {
245 gwlarson 3.3 if (tempfile[0])
246     unlink(tempfile);
247 gwlarson 3.1 exit(code);
248     }