ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.10
Committed: Thu May 29 16:26:22 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.9: +1 -1 lines
Log Message:
Changed beam offset from long to off_t, so holodecks can grow to max. length

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * Optimize holodeck for quick access.
6 *
7 * 11/4/98 Greg Ward Larson
8 */
9
10 #include "holo.h"
11
12 #include <signal.h>
13
14 #ifndef BKBSIZE
15 #define BKBSIZE 256 /* beam clump size (kilobytes) */
16 #endif
17
18 char *progname;
19 char tempfile[128];
20 int dupchecking = 0;
21
22 extern char *rindex();
23 extern long rhinitcopy();
24
25
26 main(argc, argv)
27 int argc;
28 char *argv[];
29 {
30 char *inpname, *outname;
31 int hdfd[2];
32 long nextipos, lastopos, thisopos;
33
34 progname = argv[0];
35 argv++; argc--; /* duplicate checking flag? */
36 if (argc > 1 && !strcmp(argv[0], "-u")) {
37 dupchecking++;
38 argv++; argc--;
39 }
40 if (argc < 1 | argc > 2) {
41 fprintf(stderr, "Usage: %s [-u] input.hdk [output.hdk]\n",
42 progname);
43 exit(1);
44 }
45 inpname = argv[0]; /* get input file */
46 argv++; argc--;
47 if (argc == 1) /* use given output file */
48 outname = argv[0];
49 else { /* else use temporary file */
50 if (access(inpname, R_OK|W_OK) < 0) { /* check permissions */
51 sprintf(errmsg, "cannot access \"%s\"", inpname);
52 error(SYSTEM, errmsg);
53 }
54 strcpy(tempfile, inpname);
55 if ((outname = rindex(tempfile, '/')) != NULL)
56 outname++;
57 else
58 outname = tempfile;
59 sprintf(outname, "rho%d.hdk", getpid());
60 outname = tempfile;
61 }
62 /* copy holodeck file header */
63 nextipos = rhinitcopy(hdfd, inpname, outname);
64 lastopos = 0L; /* copy sections one by one */
65 while (nextipos != 0L) {
66 /* set input position; get next */
67 lseek(hdfd[0], (off_t)nextipos, 0);
68 read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
69 /* get output position; set last */
70 thisopos = lseek(hdfd[1], (off_t)0L, 2);
71 if (lastopos > 0L) {
72 lseek(hdfd[1], (off_t)lastopos, 0);
73 write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
74 lseek(hdfd[1], (off_t)0L, 2);
75 }
76 lastopos = thisopos;
77 thisopos = 0L; /* write place holder */
78 write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
79 /* copy holodeck section */
80 copysect(hdfd[0], hdfd[1]);
81 }
82 /* clean up */
83 close(hdfd[0]);
84 close(hdfd[1]);
85 if (outname == tempfile && rename(outname, inpname) < 0) {
86 sprintf(errmsg, "cannot rename \"%s\" to \"%s\"",
87 outname, inpname);
88 error(SYSTEM, errmsg);
89 }
90 exit(0);
91 }
92
93
94 long
95 rhinitcopy(hfd, infn, outfn) /* open files and copy header */
96 int hfd[2]; /* returned file descriptors */
97 char *infn, *outfn;
98 {
99 FILE *infp, *outfp;
100 long ifpos;
101 /* open files for i/o */
102 if ((infp = fopen(infn, "r")) == NULL) {
103 sprintf(errmsg, "cannot open \"%s\" for reading", infn);
104 error(SYSTEM, errmsg);
105 }
106 if (access(outfn, F_OK) == 0) {
107 sprintf(errmsg, "output file \"%s\" already exists!", outfn);
108 error(USER, errmsg);
109 }
110 if ((outfp = fopen(outfn, "w+")) == NULL) {
111 sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
112 error(SYSTEM, errmsg);
113 }
114 /* 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 /* copy and verify header */
123 if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC)
124 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 /* check cache size */
137 if (BKBSIZE*1024*1.5 > hdcachesize)
138 hdcachesize = BKBSIZE*1024*1.5;
139 /* return input position */
140 return(ifpos);
141 }
142
143
144 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 static BEAMI *beamdir;
170
171 static int
172 bpcmp(b1p, b2p) /* compare beam positions on disk */
173 int *b1p, *b2p;
174 {
175 register off_t pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
176
177 if (pdif < 0L) return(-1);
178 return(pdif > 0L);
179 }
180
181 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 int n;
191
192 beamdir = hp->bi; /* sort based on file position */
193 qsort((void *)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 DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
198 n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
199 bcopy((void *)hdbray(bp), (void *)hdnewrays(hout,bq[i],n),
200 n*sizeof(RAYVAL));
201 hdfreebeam(hp, bq[i]);
202 }
203 hdfreebeam(hout, 0); /* write & free clump */
204 return(0);
205 }
206
207 copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */
208 int ifd, ofd;
209 {
210 HOLO *hinp;
211 /* load input section directory */
212 hinp = hdinit(ifd, NULL);
213 /* create output section directory */
214 hout = hdinit(ofd, (HDGRID *)hinp);
215 /* clump the beams */
216 clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
217 /* clean up */
218 hddone(hinp);
219 hddone(hout);
220 }
221
222
223 void
224 eputs(s) /* put error message to stderr */
225 register char *s;
226 {
227 static int midline = 0;
228
229 if (!*s)
230 return;
231 if (!midline++) { /* prepend line with program name */
232 fputs(progname, stderr);
233 fputs(": ", stderr);
234 }
235 fputs(s, stderr);
236 if (s[strlen(s)-1] == '\n') {
237 fflush(stderr);
238 midline = 0;
239 }
240 }
241
242
243 void
244 quit(code) /* exit the program gracefully */
245 int code;
246 {
247 if (tempfile[0])
248 unlink(tempfile);
249 exit(code);
250 }