ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpict.c
Revision: 1.2
Committed: Mon Apr 10 09:32:55 1989 UTC (35 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +2 -0 lines
Log Message:
Added warnings for inappropriate recover files

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * rpict.c - routines and variables for picture generation.
9 *
10 * 8/14/85
11 */
12
13 #include "ray.h"
14
15 #ifdef BSD
16 #include <sys/time.h>
17 #include <sys/resource.h>
18 #endif
19
20 #include "view.h"
21
22 #include "random.h"
23
24 VIEW ourview = STDVIEW(512); /* view parameters */
25
26 int psample = 4; /* pixel sample size */
27
28 double maxdiff = .05; /* max. difference for interpolation */
29
30 double dstrpix = 0.67; /* square pixel distribution */
31 double dstrsrc = 0.0; /* square source distribution */
32
33 int maxdepth = 6; /* maximum recursion depth */
34 double minweight = 5e-3; /* minimum ray weight */
35
36 COLOR ambval = BLKCOLOR; /* ambient value */
37 double ambacc = 0.2; /* ambient accuracy */
38 int ambres = 128; /* ambient resolution */
39 int ambdiv = 128; /* ambient divisions */
40 int ambssamp = 0; /* ambient super-samples */
41 int ambounce = 0; /* ambient bounces */
42 char *amblist[128]; /* ambient include/exclude list */
43 int ambincl = -1; /* include == 1, exclude == 0 */
44
45 int ralrm = 0; /* seconds between reports */
46
47 double pctdone = 0.0; /* percentage done */
48
49 extern long nrays; /* number of rays traced */
50
51 #define MAXDIV 32 /* maximum sample size */
52
53 #define pixjitter() (.5+dstrpix*(.5-frandom()))
54
55
56 quit(code) /* quit program */
57 int code;
58 {
59 if (code || ralrm > 0) /* report status */
60 report();
61
62 exit(code);
63 }
64
65
66 report() /* report progress */
67 {
68 #ifdef BSD
69 struct rusage rubuf;
70 double t;
71
72 getrusage(RUSAGE_SELF, &rubuf);
73 t = (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
74 t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
75 getrusage(RUSAGE_CHILDREN, &rubuf);
76 t += (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
77 t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
78
79 sprintf(errmsg, "%ld rays, %4.2f%% done after %5.4f CPU hours\n",
80 nrays, pctdone, t/3600.0);
81 #else
82 sprintf(errmsg, "%ld rays, %4.2f%% done\n", nrays, pctdone);
83 #endif
84 eputs(errmsg);
85
86 if (ralrm > 0)
87 alarm(ralrm);
88 }
89
90
91 render(oldfile) /* render the scene */
92 char *oldfile;
93 {
94 COLOR *scanbar[MAXDIV+1]; /* scanline arrays of pixel values */
95 int ypos; /* current scanline */
96 COLOR *colptr;
97 register int i;
98
99 if (psample < 1)
100 psample = 1;
101 else if (psample > MAXDIV)
102 psample = MAXDIV;
103
104 ourview.hresolu -= ourview.hresolu % psample;
105 ourview.vresolu -= ourview.vresolu % psample;
106
107 for (i = 0; i <= psample; i++) {
108 scanbar[i] = (COLOR *)malloc((ourview.hresolu+1)*sizeof(COLOR));
109 if (scanbar[i] == NULL)
110 error(SYSTEM, "out of memory in render");
111 }
112
113 /* write out boundaries */
114 printf("-Y %d +X %d\n", ourview.vresolu, ourview.hresolu);
115
116 ypos = ourview.vresolu - salvage(oldfile); /* find top line */
117 fillscanline(scanbar[0], ypos, psample); /* top scan */
118
119 for (ypos -= psample; ypos > -psample; ypos -= psample) {
120
121 colptr = scanbar[psample]; /* get last scanline */
122 scanbar[psample] = scanbar[0];
123 scanbar[0] = colptr;
124
125 fillscanline(scanbar[0], ypos, psample); /* base scan */
126
127 fillscanbar(scanbar, ypos, psample);
128
129 for (i = psample-1; i >= 0; i--)
130 if (fwritescan(scanbar[i], ourview.hresolu, stdout) < 0)
131 goto writerr;
132 if (fflush(stdout) == EOF)
133 goto writerr;
134 pctdone = 100.0*(ourview.vresolu-ypos)/ourview.vresolu;
135 }
136
137 for (i = 0; i <= psample; i++)
138 free((char *)scanbar[i]);
139 return;
140 writerr:
141 error(SYSTEM, "write error in render");
142 }
143
144
145 fillscanline(scanline, y, xstep) /* fill scan line at y */
146 register COLOR *scanline;
147 int y, xstep;
148 {
149 int b = xstep;
150 register int i;
151
152 pixvalue(scanline[0], 0, y);
153
154 for (i = xstep; i <= ourview.hresolu; i += xstep) {
155
156 pixvalue(scanline[i], i, y);
157
158 b = fillsample(scanline+i-xstep, i-xstep, y, xstep, 0, b/2);
159 }
160 }
161
162
163 fillscanbar(scanbar, y, ysize) /* fill interior */
164 register COLOR *scanbar[];
165 int y, ysize;
166 {
167 COLOR vline[MAXDIV+1];
168 int b = ysize;
169 register int i, j;
170
171 for (i = 0; i < ourview.hresolu; i++) {
172
173 copycolor(vline[0], scanbar[0][i]);
174 copycolor(vline[ysize], scanbar[ysize][i]);
175
176 b = fillsample(vline, i, y, 0, ysize, b/2);
177
178 for (j = 1; j < ysize; j++)
179 copycolor(scanbar[j][i], vline[j]);
180 }
181 }
182
183
184 int
185 fillsample(colline, x, y, xlen, ylen, b) /* fill interior points */
186 register COLOR *colline;
187 int x, y;
188 int xlen, ylen;
189 int b;
190 {
191 double ratio;
192 COLOR ctmp;
193 int ncut;
194 register int len;
195
196 if (xlen > 0) /* x or y length is zero */
197 len = xlen;
198 else
199 len = ylen;
200
201 if (len <= 1) /* limit recursion */
202 return(0);
203
204 if (b > 0 || bigdiff(colline[0], colline[len], maxdiff)) {
205
206 pixvalue(colline[len>>1], x + (xlen>>1), y + (ylen>>1));
207 ncut = 1;
208
209 } else { /* interpolate */
210
211 copycolor(colline[len>>1], colline[len]);
212 ratio = (double)(len>>1) / len;
213 scalecolor(colline[len>>1], ratio);
214 copycolor(ctmp, colline[0]);
215 ratio = 1.0 - ratio;
216 scalecolor(ctmp, ratio);
217 addcolor(colline[len>>1], ctmp);
218 ncut = 0;
219 }
220 /* recurse */
221 ncut += fillsample(colline, x, y, xlen>>1, ylen>>1, (b-1)/2);
222
223 ncut += fillsample(colline + (len>>1), x + (xlen>>1), y + (ylen>>1),
224 xlen - (xlen>>1), ylen - (ylen>>1), b/2);
225
226 return(ncut);
227 }
228
229
230 pixvalue(col, x, y) /* compute pixel value */
231 COLOR col; /* returned color */
232 int x, y; /* pixel position */
233 {
234 static RAY thisray; /* our ray for this pixel */
235
236 rayview(thisray.rorg, thisray.rdir, &ourview,
237 x + pixjitter(), y + pixjitter());
238
239 rayorigin(&thisray, NULL, PRIMARY, 1.0);
240
241 rayvalue(&thisray); /* trace ray */
242
243 copycolor(col, thisray.rcol); /* return color */
244 }
245
246
247 int
248 salvage(oldfile) /* salvage scanlines from killed program */
249 char *oldfile;
250 {
251 COLR *scanline;
252 FILE *fp;
253 int x, y;
254
255 if (oldfile == NULL)
256 return(0);
257 else if ((fp = fopen(oldfile, "r")) == NULL) {
258 sprintf(errmsg, "cannot open recover file \"%s\"", oldfile);
259 error(WARNING, errmsg);
260 return(0);
261 }
262 /* discard header */
263 getheader(fp, NULL);
264 /* get picture size */
265 if (fscanf(fp, "-Y %d +X %d\n", &y, &x) != 2) {
266 sprintf(errmsg, "bad recover file \"%s\"", oldfile);
267 error(WARNING, errmsg);
268 fclose(fp);
269 return(0);
270 }
271
272 if (x != ourview.hresolu || y != ourview.vresolu) {
273 sprintf(errmsg, "resolution mismatch in recover file \"%s\"",
274 oldfile);
275 error(USER, errmsg);
276 return(0);
277 }
278
279 scanline = (COLR *)malloc(ourview.hresolu*sizeof(COLR));
280 if (scanline == NULL)
281 error(SYSTEM, "out of memory in salvage");
282 for (y = 0; y < ourview.vresolu; y++) {
283 if (freadcolrs(scanline, ourview.hresolu, fp) < 0)
284 break;
285 if (fwritecolrs(scanline, ourview.hresolu, stdout) < 0)
286 goto writerr;
287 }
288 if (fflush(stdout) == EOF)
289 goto writerr;
290 free((char *)scanline);
291 fclose(fp);
292 unlink(oldfile);
293 return(y);
294 writerr:
295 error(SYSTEM, "write error in salvage");
296 }