ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.18
Committed: Thu Jan 1 11:21:55 2004 UTC (20 years, 3 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9
Changes since 3.17: +41 -22 lines
Log Message:
Ansification and prototypes.

File Contents

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